home *** CD-ROM | disk | FTP | other *** search
/ Aminet 49 / Aminet 49 (2002)(GTI - Schatztruhe)[!][Jun 2002].iso / Aminet / util / misc / ReportPlus.lha / ReportPlus / source / f6.c < prev    next >
C/C++ Source or Header  |  2002-04-15  |  185KB  |  4,650 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <intuition/intuition.h>
  4. #include <intuition/gadgetclass.h>
  5. #include <libraries/gadtools.h>
  6. #include <libraries/iffparse.h>
  7. #include <graphics/gfx.h>
  8. #include <dos/dos.h>
  9. #include <dos/datetime.h>
  10.  
  11. #include <clib/alib_protos.h>
  12. #include <clib/exec_protos.h>
  13. #include <clib/intuition_protos.h>
  14. #include <clib/gadtools_protos.h>
  15. #include <clib/iffparse_protos.h>
  16. #include <clib/dos_protos.h>
  17. #include <clib/graphics_protos.h>
  18.  
  19. #include <ctype.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "rp.h"
  23.  
  24. #define BYTESPERLINE 12 // how many bytes to print per line
  25.  
  26. #define ITEMS 255
  27. MODULE struct
  28. {   TEXT   name[5];
  29.     ULONG  bytes;
  30.     UBYTE* DataPtr;
  31. } contents[ITEMS + 1];
  32.  
  33. #define FORMS         89
  34.  
  35. #define CD             1
  36. #define OBSOLETE       2
  37. #define PRIVATE        4
  38. #define PROPOSAL       8
  39. #define RESERVED      16
  40. #define RKM           32
  41. #define STANDARD      64
  42. #define UNREGISTERED 128
  43.  
  44. #define LIST1LINES    25
  45.  
  46. #define IFFXCHARS     17
  47.  
  48. MODULE void iffquery(void);
  49. MODULE void PrintTopChunk(void);
  50. MODULE void readiff(void);
  51. MODULE void tellchunk(UWORD which);
  52. MODULE void chunkdesc(STRPTR desc, ABOOL isknown);
  53. MODULE void binarize(UBYTE data);
  54. MODULE void hexalize(UBYTE data);
  55. MODULE ULONG getulong(UBYTE* start);
  56. MODULE SLONG getslong(UBYTE* start);
  57. MODULE ULONG getuword(UBYTE* start);
  58. MODULE SLONG getsword(UBYTE* start);
  59. MODULE SLONG getsbyte(UBYTE* start);
  60. MODULE void writeiffgadgets(void);
  61. MODULE void dotextattr(UBYTE* offset);
  62. MODULE void docountry(UBYTE* offset);
  63. MODULE void tellchunk(UWORD which);
  64.  
  65. /* Text error messages for possible IFFERR_#? returns from various IFF
  66.  * routines. To get the index into this array, take your IFFERR code,
  67.  * negate it, and subtract one.
  68.  * idx = -error - 1;
  69.  */
  70. STRPTR errormsgs[] =
  71. {   "End of file (not an error).",
  72.     "End of context (not an error).",
  73.     "No lexical scope.",
  74.     "Insufficient memory.",
  75.     "Stream read error.",
  76.     "Stream write error.",
  77.     "Stream seek error.",
  78.     "File is corrupt.",
  79.     "IFF syntax error.",
  80.     "Not an IFF file.",
  81.     "Required call-back hook missing.",
  82.     "Return to client. You should never see this."
  83. };
  84.  
  85. // from rp.c
  86. IMPORT ABOOL              fillwindows;
  87. IMPORT SBYTE              page;
  88. IMPORT struct NewGadget   Gadget;
  89. IMPORT struct Gadget     *BU99_Right,
  90.                          *PrevGadPtr;
  91. IMPORT struct Window*     MainWindowPtr;
  92. IMPORT struct VisualInfo* VisualInfoPtr;
  93. IMPORT TEXT               aslresult[VLONGFIELD + 1],
  94.                           weekdaystring[LEN_DATSTRING],
  95.                           datestring[LEN_DATSTRING],
  96.                           timestring[LEN_DATSTRING],
  97.                           IOBuffer[LONGESTFIELD + 1];
  98. IMPORT ULONG              fillcolour;
  99.  
  100. MODULE ABOOL             known, first;
  101. MODULE struct IFFHandle* IFFHandle             = NULL;
  102. MODULE struct List       List1,
  103.                          List2;
  104. MODULE ABOOL             List1Nodes            = FALSE,
  105.                          List2Nodes            = FALSE;
  106. MODULE struct Gadget  *TE61_Contributor        = NULL,
  107.                       *CB61_CD                 = NULL,
  108.                       *CB61_Obsolete           = NULL,
  109.                       *TE61_FORMDesc           = NULL,
  110.                       *ST61_FORMID             = NULL,
  111.                       *CB61_Private            = NULL,
  112.                       *CB61_Proposal           = NULL,
  113.                       *CB61_Reserved           = NULL,
  114.                       *CB61_RKM                = NULL,
  115.                       *CB61_Standard           = NULL,
  116.                       *CB61_Unregistered       = NULL,
  117.                       *CB61_Raw                = NULL,
  118.                       *TE61_Status             = NULL,
  119.                       *ST61_Pathname           = NULL,
  120.                       *BU61_PathnameASL        = NULL,
  121.                       *LV61_List1              = NULL,
  122.                       *LV61_List2              = NULL,
  123.                       *TE61_ChunkDesc          = NULL;
  124. MODULE TEXT  queryform[5] = "",
  125.              tempstring1[VLONGFIELD + 1],
  126.              tempstring2[13];
  127. MODULE ULONG items      = 0, // value of this is actual number of items allocated
  128.              list1lines = 0;
  129. MODULE UWORD selectedform  = 0,
  130.              selectedchunk = 0;
  131.  
  132. AGLOBAL struct IFFStruct iff;
  133.  
  134. MODULE struct
  135. {   UBYTE  flags;
  136.     TEXT   name[5];
  137.     STRPTR desc;
  138.     STRPTR contributor;
  139. } form[FORMS + 1] =
  140. {   STANDARD | RKM | CD,      "8SVX", "EA IFF 85 8-bit sound sample form",                    "EA/CBM",
  141.     RKM | CD,                 "AIFF", "Audio 1-32 bit samples",                               "Apple",
  142.     RKM | CD,                 "ACBM", "Amiga Contiguous Bitmap",                              "CBM",
  143.     UNREGISTERED,             "AHAM", "?",                                                    "?",
  144.     RKM | CD,                 "ANBM", "ANimated BitMap form",                                 "EA",
  145.     RKM | CD,                 "ANIM", "Cel ANIMation form",                                   "Sparta/Aegis",
  146.     PROPOSAL,                 "ARC ", "ARChive format",                                       "?",
  147.     UNREGISTERED,             "ARES", "?",                                                    "?",
  148.     RESERVED,                 "ATXT", "Temporarily reserved",                                 "?",
  149.     PRIVATE,                  "AVCF", "AmigaVision Flow",                                     "CBM",
  150.     NULL,                     "BANK", "Soundquest Editor/Librarian MIDI Sysex dump",          "?",
  151.     NULL,                     "BBSD", "BBS Database",                                         "Phalanx Software",
  152.     PRIVATE,                  "C100", "?",                                                    "Cloanto",
  153.     STANDARD,                 "CAT ", "EA IFF 85 group identifier",                           "EA/CBM",
  154.     PROPOSAL,                 "CELP", "Compressed ZyXEL voice data",                          "?",
  155.     RESERVED,                 "CHBM", "Chunky bitmap",                                        "Eric Lavitsky",
  156.     NULL,                     "CLIP", "CAT CLIP to hold various formats in clipboard",        "CBM",
  157.     PROPOSAL | CD,            "CMUS", "Common MUsical Score",                                 "Talin (David Joiner)",
  158.     NULL,                     "CPFM", "Cloanto Personal FontMaker",                           "Cloanto",
  159.     NULL,                     "DCCL", "DCTV paint clip",                                      "?",
  160.     NULL,                     "DCPA", "DCTV paint palette",                                   "?",
  161.     NULL,                     "DCTV", "DCTV raw picture file",                                "?",
  162.     PRIVATE,                  "DECK", "Inovatronics CanDo",                                   "Innovatronics",
  163.     CD,                       "DEEP", "Chunky pixel image files (used in TV Paint)",          "Amiga Centre Scotland",
  164.     RKM | CD,                 "DR2D", "2D object standard format",                            "Ross Cunniff & John Orr",
  165.     RESERVED,                 "DRAW", "?",                                                    "Jim Bayless",
  166.     CD,                       "DTYP", "DataTYPes identification",                             "Amiga, Inc.",
  167.     PROPOSAL | CD,            "EXEC", "Executable (loadseg-able) code",                       "Chris Ludwig",
  168.     RKM | CD,                 "FANT", "Fantavision movie format",                             "Broderbund",
  169.     OBSOLETE | PRIVATE,       "FAX3", "Facsimile image",                                      "GPSoftware",
  170.     CD,                       "FAXX", "Facsimile image",                                      "Atlantis Design Group",
  171.     RESERVED,                 "FIGR", "Deluxe Video",                                         "EA",
  172.     NULL,                     "FILM", "LIST FILM - stores ILBMs with interleaved 8SVX audio", "?",
  173.     RESERVED,                 "FNTR", "Raster font",                                          "EA",
  174.     RESERVED,                 "FNTV", "Vector font",                                          "EA",
  175.     STANDARD,                 "FORM", "Group identifier",                                     "EA/CBM",
  176.     STANDARD | RKM,           "FTXT", "Formatted TeXT",                                       "EA/CBM",
  177.     PROPOSAL | PRIVATE,       "GRYP", "Byteplane storage",                                    "?",
  178.     RESERVED,                 "GSCR", "General music SCoRe",                                  "EA",
  179.     PROPOSAL | PRIVATE,       "GUI ", "User interface storage",                               "?",
  180.     RKM | CD,                 "HEAD", "Flow idea processor",                                  "New Horizons Software",
  181.     STANDARD | RKM | CD,      "ILBM", "EA IFF 85 raster bitmap form",                         "EA/CBM",
  182.     RESERVED,                 "IOBJ", "?",                                                    "Seven Seas Software",
  183.     RESERVED,                 "IODK", "?",                                                    "Merging Technologies",
  184.     RESERVED,                 "ITRF", "?",                                                    "?",
  185.     RESERVED,                 "JMOV", "?",                                                    "Merging Technologies",
  186.     STANDARD,                 "LIST", "EA IFF 85 group identifier",                           "EA/CBM",
  187.     RESERVED,                 "MFAX", "Facsimile?",                                           "TKR GmbH & Co.",
  188.     NULL,                     "MIDI", "MIDI?",                                                "Circum Design",
  189.     PRIVATE,                  "MOVI", "LIST MOVIe?",                                          "?",
  190.     PRIVATE,                  "MSCX", "Music-X format",                                       "?",
  191.     RESERVED,                 "MSMP", "Temporarily reserved",                                 "?",
  192.     RKM | CD,                 "MTRX", "Numerical data storage (MathVision)",                  "Seven Seas Software",
  193.     NULL,                     "NSEQ", "Numerical sequence",                                   "Stockhausen GmbH",
  194.     PROPOSAL | CD,            "OB3D", "Standard 3D object",                                   "?",
  195.     RKM | CD,                 "PGTB", "ProGram TraceBack",                                    "SAS Institute",
  196.     RESERVED,                 "PICS", "Macintosh picture",                                    "EA",
  197.     RESERVED | OBSOLETE,      "PLBM", "?",                                                    "EA",
  198.     RESERVED | PROPOSAL | CD, "PMBC", "24-bit accurate images",                               "Black Belt Systems",
  199.     RESERVED | PRIVATE,       "PREF", "User preferences data",                                "CBM",
  200.     STANDARD,                 "PROP", "Group identifier",                                     "EA/CBM",
  201.     RKM | CD,                 "PRSP", "DPaint IV perspective move form",                      "EA",
  202.     NULL,                     "PTCH", "Patch file",                                           "SAS Institute",
  203.     RESERVED,                 "PTXT", "Temporarily reserved",                                 "?",
  204.     NULL,                     "RGB4", "4-bit RGB",                                            "?",
  205.     RKM | CD,                 "RGB8", "RGB image (Turbo Silver)",                             "Impulse",
  206.     RKM | CD,                 "RGBN", "RGB image (Turbo Silver)",                             "Impulse",
  207.     RESERVED,                 "RGBX", "Temporarily reserved",                                 "?",
  208.     PRIVATE,                  "ROXN", "Animation",                                            "?",
  209.     RKM | CD,                 "SAMP", "SAMPled sound",                                        "Jim Fiore & Jeff Glatt",
  210.     PRIVATE,                  "SC3D", "SCene format (Sculpt-3D)",                             "?",
  211.     PRIVATE,                  "SHAK", "SHAKespeare format",                                   "?",
  212.     RESERVED | PRIVATE,       "SHO1", "?",                                                    "Gary Bonham",
  213.     RESERVED | PRIVATE,       "SHOW", "?",                                                    "Gary Bonham",
  214.     STANDARD | RKM,           "SMUS", "Simple MUsic Score",                                   "EA/CBM",
  215.     CD,                       "SPLT", "File SPLiTting system",                                "ASDG",
  216.     RESERVED,                 "SSRE", "?",                                                    "Merging Technologies",
  217.     UNREGISTERED,             "SWRT", "?",                                                    "?",
  218.     NULL,                     "SYTH", "SoundQuest Master Librarian MIDI System driver",       "?",
  219.     RESERVED,                 "TCDE", "?",                                                    "Merging Technologies",
  220.     RKM | CD,                 "TDDD", "3D rendering data (Turbo Silver)",                     "Impulse",
  221.     UNREGISTERED,             "TERM", "?",                                                    "?",
  222.     CD,                       "TMUI", "ToolMaker User Interface",                             "Michael Erwin",
  223.     CD,                       "TREE", "Arbitrary data structures as trees (or nested lists)", "Stefan Reisner",
  224.     CD | PROPOSAL,            "TRKR", "TRacKeR style music module",                           "Full Tilt Entertainment",
  225.     RESERVED,                 "USCR", "Uhuru SCoRe",                                          "EA",
  226.     RESERVED,                 "UVOX", "Uhuru Macintosh VOiXe",                                "EA",
  227.     PRIVATE,                  "VDEO", "Deluxe ViDEO",                                         "EA",
  228.     RKM | CD,                 "WORD", "ProWrite document",                                    "New Horizons Software",
  229.     CD,                       "YUVN", "For storage of Y:U:V image data",                      "MacroSystem"
  230. };
  231.  
  232. AGLOBAL void iff1(void)
  233. {   verynewwindow
  234.     (   IFF1WIDTH, IFF1HEIGHT,
  235.         "Report+: IFF Registry",
  236.         BUTTONIDCMP | STRINGIDCMP | LISTVIEWIDCMP
  237.     );
  238.     if (fillwindows)
  239.     {   SetAPen(MainWindowPtr->RPort, 0);
  240.         RectFill(MainWindowPtr->RPort,  10, 136,  10 + 160, 136 + 204 - 1); // LV61_List1
  241.         RectFill(MainWindowPtr->RPort, 180, 136, 180 + 450, 136 + 204 - 1); // LV61_List2
  242.         RectFill(MainWindowPtr->RPort, 130,  34, 130 + 334,  34 +  12    ); // TE61_FORMDesc
  243.         RectFill(MainWindowPtr->RPort, 130,  46, 130 + 334,  46 +  12    ); // TE61_Contributor
  244.         RectFill(MainWindowPtr->RPort, 130,  58, 130 + 334,  58 +  12    ); // TE61_ChunkDesc
  245.         RectFill(MainWindowPtr->RPort, 130, 352, 130 + 350, 352 +  12    ); // TE61_Status
  246.     }
  247.  
  248.     /* FORM ID */
  249.     setgadget(130, 22, 56, 12, "_FORM ID:", NULL);
  250.     ST61_FORMID = PrevGadPtr = (struct Gadget *) CreateGadget
  251.     (   STRING_KIND,
  252.         PrevGadPtr,
  253.         &Gadget,
  254.         GTST_String, queryform,
  255.         GTST_MaxChars, 4,
  256.         GA_TabCycle, TRUE,
  257.         GA_Immediate, TRUE,
  258.         GT_Underscore, '_',
  259.         STRINGA_ReplaceMode, TRUE,
  260.         TAG_DONE
  261.     );
  262.     /* FORM description */
  263.     setgadget(130, 34, 334, 12, "Description:", NULL);
  264.     TE61_FORMDesc = PrevGadPtr = (struct Gadget *) CreateGadget
  265.     (   TEXT_KIND,
  266.         PrevGadPtr,
  267.         &Gadget,
  268.         GTTX_Text, "-",
  269.         GTTX_Border, TRUE,
  270.         TAG_DONE
  271.     );
  272.     /* contributor name */
  273.     setgadget(130, 46, 334, 12, "Contributor:", NULL);
  274.     TE61_Contributor = PrevGadPtr = (struct Gadget *) CreateGadget
  275.     (   TEXT_KIND,
  276.         PrevGadPtr,
  277.         &Gadget,
  278.         GTTX_Text, "-",
  279.         GTTX_Border, TRUE,
  280.         TAG_DONE
  281.     );
  282.     /* chunk description */
  283.     setgadget(130, 58, 334, 12, "Chunk info:", NULL);
  284.     TE61_ChunkDesc = PrevGadPtr = (struct Gadget *) CreateGadget
  285.     (   TEXT_KIND,
  286.         PrevGadPtr,
  287.         &Gadget,
  288.         GTTX_Text, "-",
  289.         GTTX_Border, TRUE,
  290.         TAG_DONE
  291.     );
  292.  
  293.     /* flags */
  294.     setgadget(596, 46, 0, 0, "Obsolete:", NULL);
  295.     CB61_Obsolete = PrevGadPtr = (struct Gadget *) CreateGadget
  296.     (   CHECKBOX_KIND,
  297.         PrevGadPtr,
  298.         &Gadget,
  299.         GA_Disabled, TRUE,
  300.         GTCB_Checked, iff.obsolete,
  301.         TAG_DONE
  302.     );
  303.     setgadget(596, 58, 0, 0, "Private:", NULL);
  304.     CB61_Private = PrevGadPtr = (struct Gadget *) CreateGadget
  305.     (   CHECKBOX_KIND,
  306.         PrevGadPtr,
  307.         &Gadget,
  308.         GA_Disabled, TRUE,
  309.         GTCB_Checked, iff.private,
  310.         TAG_DONE
  311.     );
  312.     setgadget(596, 70, 0, 0, "Proposal:", NULL);
  313.     CB61_Proposal = PrevGadPtr = (struct Gadget *) CreateGadget
  314.     (   CHECKBOX_KIND,
  315.         PrevGadPtr,
  316.         &Gadget,
  317.         GA_Disabled, TRUE,
  318.         GTCB_Checked, iff.proposal,
  319.         TAG_DONE
  320.     );
  321.     setgadget(596, 82, 0, 0, "Reserved:", NULL);
  322.     CB61_Reserved = PrevGadPtr = (struct Gadget *) CreateGadget
  323.     (   CHECKBOX_KIND,
  324.         PrevGadPtr,
  325.         &Gadget,
  326.         GA_Disabled, TRUE,
  327.         GTCB_Checked, iff.reserved,
  328.         TAG_DONE
  329.     );
  330.     setgadget(596, 94, 0, 0, "Standard:", NULL);
  331.     CB61_Standard = PrevGadPtr = (struct Gadget *) CreateGadget
  332.     (   CHECKBOX_KIND,
  333.         PrevGadPtr,
  334.         &Gadget,
  335.         GA_Disabled, TRUE,
  336.         GTCB_Checked, iff.standard,
  337.         TAG_DONE
  338.     );
  339.     setgadget(596, 106, 0, 0, "Unregistered:", NULL);
  340.     CB61_Unregistered = PrevGadPtr = (struct Gadget *) CreateGadget
  341.     (   CHECKBOX_KIND,
  342.         PrevGadPtr,
  343.         &Gadget,
  344.         GA_Disabled, TRUE,
  345.         GTCB_Checked, iff.unregistered,
  346.         TAG_DONE
  347.     );
  348.  
  349.     setgadget(596, 364, 0, 0, "RKM:", NULL);
  350.     CB61_RKM = PrevGadPtr = (struct Gadget *) CreateGadget
  351.     (   CHECKBOX_KIND,
  352.         PrevGadPtr,
  353.         &Gadget,
  354.         GA_Disabled, TRUE,
  355.         GTCB_Checked, iff.rkm,
  356.         TAG_DONE
  357.     );
  358.     setgadget(596, 376, 0, 0, "ADCD 2.1:", NULL);
  359.     CB61_CD = PrevGadPtr = (struct Gadget *) CreateGadget
  360.     (   CHECKBOX_KIND,
  361.         PrevGadPtr,
  362.         &Gadget,
  363.         GA_Disabled, TRUE,
  364.         GTCB_Checked, iff.cd,
  365.         TAG_DONE
  366.     );
  367.  
  368.     setgadget( 10, 136, 160, 204, "Chunks:", NULL);
  369.     LV61_List1 = PrevGadPtr = (struct Gadget *) CreateGadget
  370.     (   LISTVIEW_KIND,
  371.         PrevGadPtr,
  372.         &Gadget,
  373.         GTLV_Labels, NULL,
  374.         GTLV_ShowSelected, NULL,
  375.         TAG_DONE
  376.     );
  377.     setgadget(180, 136, 450, 204, "Chunk contents:", NULL);
  378.     LV61_List2 = PrevGadPtr = (struct Gadget *) CreateGadget
  379.     (   LISTVIEW_KIND,
  380.         PrevGadPtr,
  381.         &Gadget,
  382.         GTLV_Labels, NULL,
  383.         TAG_DONE
  384.     );
  385.  
  386.     /* status */
  387.     setgadget(130, 352, 350, 12, "Status:", NULL);
  388.     TE61_Status = PrevGadPtr = (struct Gadget *) CreateGadget
  389.     (   TEXT_KIND,
  390.         PrevGadPtr,
  391.         &Gadget,
  392.         GTTX_Text, "Ready.",
  393.         GTTX_Border, TRUE,
  394.         TAG_DONE
  395.     );
  396.  
  397.     /* pathname */
  398.     setgadget(130, 364, 320, 12, "_Pathname:", NULL);
  399.     ST61_Pathname = PrevGadPtr = (struct Gadget *) CreateGadget
  400.     (   STRING_KIND,
  401.         PrevGadPtr,
  402.         &Gadget,
  403.         GTST_String, iff.pathname,
  404.         GTST_MaxChars, VLONGFIELD,
  405.         GA_TabCycle, TRUE,
  406.         GA_Immediate, TRUE,
  407.         GT_Underscore, '_',
  408.         TAG_DONE
  409.     );
  410.  
  411.     /* pathname... */
  412.     setgadget(452, 364, 28, 12, "_...", NULL);
  413.     BU61_PathnameASL = PrevGadPtr = (struct Gadget *) CreateGadget
  414.     (   BUTTON_KIND,
  415.         PrevGadPtr,
  416.         &Gadget,
  417.         GT_Underscore, '_',
  418.         TAG_DONE
  419.     );
  420.  
  421.     setgadget(130, 82, 0, 0, "_Raw view only?", PLACETEXT_RIGHT);
  422.     CB61_Raw = PrevGadPtr = (struct Gadget *) CreateGadget
  423.     (   CHECKBOX_KIND,
  424.         PrevGadPtr,
  425.         &Gadget,
  426.         GTCB_Checked, iff.raw,
  427.         GT_Underscore, '_',
  428.         TAG_DONE
  429.     );
  430.  
  431.     drawgadgets((UWORD) ~0);
  432.  
  433.     SetDrMd(MainWindowPtr->RPort, JAM2);
  434.     SetAPen(MainWindowPtr->RPort, BLACK);
  435.     if (fillwindows)
  436.     {   getfillcolour();
  437.         SetBPen(MainWindowPtr->RPort, fillcolour);
  438.     }
  439.  
  440.     DrawBevelBox(MainWindowPtr->RPort, 474,  34, 156, 18 + (12 * 6), GT_VisualInfo, VisualInfoPtr, GTBB_Recessed, TRUE, TAG_END);
  441.     Move(MainWindowPtr->RPort, 474 + (156 / 2) - ((15 * FONTX) / 2),  34 + (FONTY / 2) - 1);
  442.     Text(MainWindowPtr->RPort, "Official Status", 15);
  443.  
  444.     DrawBevelBox(MainWindowPtr->RPort, 490, 352, 140, 18 + (12 * 2), GT_VisualInfo, VisualInfoPtr, GTBB_Recessed, TRUE, TAG_END);
  445.     Move(MainWindowPtr->RPort, 560             - ((13 * FONTX) / 2), 352 + (FONTY / 2) - 1);
  446.     Text(MainWindowPtr->RPort, "Documentation", 13);
  447.  
  448.     if (iff.pathname[0])
  449.     {   readiff();
  450.     } elif (queryform[0])
  451.     {   iffquery();
  452.     }
  453.     ActivateGadget(ST61_Pathname, MainWindowPtr, NULL);
  454.     loop();
  455.     strcpy
  456.     (   queryform,
  457.         ((struct StringInfo *) ST61_FORMID->SpecialInfo)->Buffer
  458.     );
  459.     strcpy
  460.     (   iff.pathname,
  461.         ((struct StringInfo *) ST61_Pathname->SpecialInfo)->Buffer
  462.     );
  463.     closewindow();
  464. }
  465.  
  466. AGLOBAL void iff_loop(ULONG class, struct Gadget* addr, UWORD code, UWORD qual)
  467. {   if (class == IDCMP_RAWKEY)
  468.     {   if (qual & IEQUALIFIER_CONTROL)
  469.         {   if (code == SCAN_UP)
  470.             {   GT_SetGadgetAttrs
  471.                 (   LV61_List1,
  472.                     MainWindowPtr,
  473.                     NULL,
  474.                     GTLV_Top, 0,
  475.                     TAG_DONE
  476.                 );
  477.             } elif (code == SCAN_DOWN)
  478.             {   if (list1lines > LIST1LINES)
  479.                 {   GT_SetGadgetAttrs
  480.                     (   LV61_List1,
  481.                         MainWindowPtr,
  482.                         NULL,
  483.                         GTLV_Top, list1lines - LIST1LINES,
  484.                         TAG_DONE
  485.                     );
  486.     }   }   }   }
  487.     elif (class == IDCMP_VANILLAKEY)
  488.     {   code = toupper(code);
  489.         if (code == ESCAPE)
  490.             page = 0;
  491.         elif (code == 'F')
  492.             ActivateGadget(ST61_FORMID, MainWindowPtr, NULL);
  493.         elif (code == 'P')
  494.             ActivateGadget(ST61_Pathname, MainWindowPtr, NULL);
  495.         elif (code == 'R')
  496.         {   if (iff.raw)
  497.             {   iff.raw = FALSE;
  498.             } else iff.raw = TRUE;
  499.             GT_SetGadgetAttrs
  500.             (   CB61_Raw,
  501.                 MainWindowPtr,
  502.                 NULL,
  503.                 GTCB_Checked, iff.raw,
  504.                 TAG_DONE
  505.             );
  506.             if (selectedchunk && known)
  507.             {   tellchunk(selectedchunk);
  508.         }   }
  509.         elif (code == '.')
  510.         {   if (asl("~(#?.info)"))
  511.             {   strcpy(iff.pathname, aslresult);
  512.                 GT_SetGadgetAttrs
  513.                 (   ST61_Pathname,
  514.                     MainWindowPtr,
  515.                     NULL,
  516.                     GTST_String, iff.pathname,
  517.                     TAG_DONE
  518.                 );
  519.                 readiff();
  520.     }   }   }
  521.     elif (class == IDCMP_GADGETUP)
  522.     {   /* IDCMP_GADGETUP is sent by the string gadget
  523.         when the user presses RETURN, ENTER, Help, Tab
  524.         or Shift-Tab inside the string gadget. */
  525.         
  526.         if (addr == BU99_Right)
  527.             page = 0;
  528.         elif (addr == CB61_Raw)
  529.         {   if (CB61_Raw->Flags & GFLG_SELECTED)
  530.             {   iff.raw = TRUE;
  531.             } else iff.raw = FALSE;
  532.             GT_SetGadgetAttrs
  533.             (   CB61_Raw,
  534.                 MainWindowPtr, NULL,
  535.                 GTCB_Checked, iff.raw,
  536.                 TAG_DONE
  537.             );
  538.             if (selectedchunk && known)
  539.             {   tellchunk(selectedchunk);
  540.         }   }
  541.         elif (addr == ST61_Pathname)
  542.     {   strcpy
  543.             (   iff.pathname,
  544.                 ((struct StringInfo *) ST61_Pathname->SpecialInfo)->Buffer
  545.         );
  546.             readiff();
  547.         } elif (addr == ST61_FORMID)
  548.         {   strcpy
  549.             (   queryform,
  550.                 ((struct StringInfo *) ST61_FORMID->SpecialInfo)->Buffer
  551.         );
  552.             iff.pathname[0] = 0;
  553.             GT_SetGadgetAttrs
  554.             (   ST61_Pathname,
  555.                 MainWindowPtr,
  556.                 NULL,
  557.                 GTST_String, iff.pathname,
  558.                 TAG_DONE
  559.             );
  560.             GT_SetGadgetAttrs
  561.             (   TE61_Status,
  562.                 MainWindowPtr,
  563.                 NULL,
  564.                 GTTX_Text, "Ready.",
  565.                 TAG_DONE
  566.             );
  567.             iffquery();
  568.         } elif (addr == BU61_PathnameASL)
  569.         {   if (asl("~(#?.info)"))
  570.             {   strcpy(iff.pathname, aslresult);
  571.                 GT_SetGadgetAttrs
  572.                 (   ST61_Pathname,
  573.                     MainWindowPtr,
  574.                     NULL,
  575.                     GTST_String, iff.pathname,
  576.                     TAG_DONE
  577.                 );
  578.                 readiff();
  579.         }   }
  580.         elif (addr == LV61_List1)
  581.         {   selectedchunk = code + 1;
  582.             tellchunk(selectedchunk);
  583. }   }   }
  584.  
  585. MODULE void iffquery(void)
  586. {   ULONG i;
  587.  
  588.     /* Make any corrections to input now, to make it
  589.     easier to search the database. */
  590.     for (i = 0; i <= 3; i++)
  591.         if (queryform[i] >= 97 && queryform[i] <= 122)
  592.             queryform[i] -= 32;
  593.         elif (queryform[i] == 0)
  594.             queryform[i] = ' ';
  595.     queryform[4] = 0;
  596.     GT_SetGadgetAttrs
  597.     (   ST61_FORMID,
  598.         MainWindowPtr,
  599.         NULL,
  600.         GTTX_Text, queryform,
  601.         TAG_DONE
  602.     );
  603.     selectedform = (UWORD) -1;
  604.     for (i = 0; i <= FORMS; i++)
  605.     if
  606.     (   queryform[0] == form[i].name[0]
  607.      && queryform[1] == form[i].name[1]
  608.      && queryform[2] == form[i].name[2]
  609.      && queryform[3] == form[i].name[3]
  610.     )
  611.     {   selectedform = i;
  612.         break;
  613.     }
  614.     selectedchunk = 0;
  615.     if (selectedform == (UWORD) -1)
  616.     {   iff.cd           =
  617.         iff.rkm          =
  618.         iff.private      =
  619.         iff.proposal     =
  620.         iff.obsolete     =
  621.         iff.reserved     =
  622.         iff.standard     =
  623.         iff.unregistered = FALSE;
  624.         GT_SetGadgetAttrs
  625.         (   TE61_FORMDesc,
  626.             MainWindowPtr,
  627.             NULL,
  628.             GTTX_Text, "-",
  629.             TAG_DONE
  630.         );
  631.         GT_SetGadgetAttrs
  632.         (   TE61_Contributor,
  633.             MainWindowPtr,
  634.             NULL,
  635.             GTTX_Text, "-",
  636.             TAG_DONE
  637.         );
  638.     } else
  639.     {   iff.cd           = form[selectedform].flags & CD;
  640.         iff.rkm          = form[selectedform].flags & RKM;
  641.         iff.private      = form[selectedform].flags & PRIVATE;
  642.         iff.proposal     = form[selectedform].flags & PROPOSAL;
  643.         iff.obsolete     = form[selectedform].flags & OBSOLETE;
  644.         iff.reserved     = form[selectedform].flags & RESERVED;
  645.         iff.standard     = form[selectedform].flags & STANDARD;
  646.         iff.unregistered = form[selectedform].flags & UNREGISTERED;
  647.         GT_SetGadgetAttrs
  648.         (   TE61_FORMDesc,
  649.             MainWindowPtr,
  650.             NULL,
  651.             GTTX_Text, form[selectedform].desc,
  652.             TAG_DONE
  653.         );
  654.         GT_SetGadgetAttrs
  655.         (   TE61_Contributor,
  656.             MainWindowPtr,
  657.             NULL,
  658.             GTTX_Text, form[selectedform].contributor,
  659.             TAG_DONE
  660.         );
  661.     }
  662.  
  663.     writeiffgadgets();
  664.  
  665.     GT_SetGadgetAttrs
  666.     (   LV61_List1,
  667.         MainWindowPtr,
  668.         NULL,
  669.         GTLV_Labels, (UWORD) ~0,
  670.         TAG_DONE
  671.     );
  672.     if (List1Nodes)
  673.     {   FreeNameNodes(&List1);
  674.         List1Nodes = FALSE;
  675.     }
  676.     NewList(&List1);
  677.     GT_SetGadgetAttrs
  678.     (   LV61_List1,
  679.         MainWindowPtr,
  680.         NULL,
  681.         GTLV_Labels, &List1,
  682.         GTLV_Selected, (UWORD) ~0,
  683.         TAG_DONE
  684.     );
  685.  
  686.     GT_SetGadgetAttrs
  687.     (   LV61_List2,
  688.         MainWindowPtr,
  689.         NULL,
  690.         GTLV_Labels, (UWORD) ~0,
  691.         TAG_DONE
  692.     );
  693.     if (List2Nodes)
  694.     {   FreeNameNodes(&List2);
  695.         List2Nodes = FALSE;
  696.     }
  697.     NewList(&List2);
  698.     GT_SetGadgetAttrs
  699.     (   LV61_List2,
  700.         MainWindowPtr,
  701.         NULL,
  702.         GTLV_Labels, &List2,
  703.         GTLV_Selected, (UWORD) ~0,
  704.         TAG_DONE
  705.     );
  706.  
  707.     for (i = 0; i < items; i++)
  708.     {   if (contents[i].DataPtr)
  709.         {   FreeMem(contents[i].DataPtr, contents[i].bytes);
  710.             contents[i].DataPtr = NULL;
  711.     }   }
  712.     items = 0;
  713. }
  714.  
  715. MODULE void readiff(void)
  716. {   LONG error;
  717.  
  718.     list1lines = 0;
  719.  
  720.     iffquery();
  721.  
  722.     /* Allocate IFF_File structure. */
  723.     if (!(IFFHandle = AllocIFF()))
  724.     {   DisplayBeep(NULL);
  725.         GT_SetGadgetAttrs
  726.         (   TE61_Status,
  727.             MainWindowPtr,
  728.             NULL,
  729.             GTTX_Text, "AllocIFF() failed!",
  730.             TAG_DONE
  731.         );
  732.         goto bye;
  733.     }
  734.  
  735.     first = TRUE;
  736.  
  737.     /* Set up IFF_File for AmigaDOS I/O.  */
  738.     if (!(IFFHandle->iff_Stream = Open(iff.pathname, MODE_OLDFILE)))
  739.     {   DisplayBeep(NULL);
  740.         GT_SetGadgetAttrs
  741.         (   TE61_Status,
  742.             MainWindowPtr,
  743.             NULL,
  744.             GTTX_Text, "Can't open file!",
  745.             TAG_DONE
  746.         );
  747.         GT_SetGadgetAttrs
  748.         (   TE61_FORMDesc,
  749.             MainWindowPtr,
  750.             NULL,
  751.             GTTX_Text, "-",
  752.             TAG_DONE
  753.         );
  754.         GT_SetGadgetAttrs
  755.         (   TE61_Contributor,
  756.             MainWindowPtr,
  757.             NULL,
  758.             GTTX_Text, "-",
  759.             TAG_DONE
  760.         );
  761.         queryform[0]     = 0;
  762.         iff.obsolete     =
  763.         iff.private      =
  764.         iff.proposal     =
  765.         iff.reserved     =
  766.         iff.standard     =
  767.         iff.unregistered =
  768.         iff.rkm          =
  769.         iff.cd           = FALSE;
  770.         writeiffgadgets();
  771.         goto bye;
  772.     }
  773.     InitIFFasDOS(IFFHandle);
  774.  
  775.     /* Start the IFF transaction. */
  776.     if (error = OpenIFF(IFFHandle, IFFF_READ))
  777.     {   DisplayBeep(NULL);
  778.         GT_SetGadgetAttrs
  779.         (   TE61_Status,
  780.             MainWindowPtr,
  781.             NULL,
  782.             GTTX_Text, "OpenIFF() failed!",
  783.             TAG_DONE
  784.         );
  785.         goto bye;
  786.     }
  787.  
  788.     while (1)
  789.     {   /* IFFPARSE_RAWSTEP permits us to have precision monitoring of the
  790.          * parsing process, which is necessary if we wish to print the
  791.          * structure of an IFF file.
  792.          *   ParseIFF() with _RAWSTEP will return the following things for
  793.          * the following reasons:
  794.          *
  795.          * Return code:                 Reason:
  796.          * 0                            Entered new context.
  797.          * IFFERR_EOC                   About to leave a context.
  798.          * IFFERR_EOF                   Encountered end-of-file.
  799.          * <anything else>              A parsing error.
  800.          */
  801.         error = ParseIFF(IFFHandle, IFFPARSE_RAWSTEP);
  802.  
  803.         /*
  804.          * Since we're only interested in when we enter a context, we
  805.          * "discard" end-of-context (_EOC) events.
  806.          */
  807.         if (error == IFFERR_EOC)
  808.             continue;
  809.         elif (error)
  810.         {   // Leave the loop if there is any other error.
  811.             break;
  812.         }
  813.  
  814.         /* If we get here, error was zero. Print out the current state of
  815.          * affairs. */
  816.         PrintTopChunk();
  817.     }
  818.  
  819.     /* If error was IFFERR_EOF, then the parser encountered the end of
  820.      * the file without problems. Otherwise, we print a diagnostic.
  821.      */
  822.     if (error == IFFERR_EOF)
  823.     {   GT_SetGadgetAttrs
  824.         (   TE61_Status,
  825.             MainWindowPtr,
  826.             NULL,
  827.             GTTX_Text, "Done.",
  828.             TAG_DONE
  829.         );
  830.         GT_SetGadgetAttrs
  831.         (   LV61_List1,
  832.             MainWindowPtr,
  833.             NULL,
  834.             GTLV_Labels, &List1,
  835.             GTLV_Selected, (UWORD) ~0,
  836.             TAG_DONE
  837.         );
  838.     } else
  839.     {   GT_SetGadgetAttrs
  840.         (   TE61_Status,
  841.             MainWindowPtr,
  842.             NULL,
  843.             GTTX_Text, errormsgs[-error - 1],
  844.             TAG_DONE
  845.         );
  846.         GT_SetGadgetAttrs
  847.         (   LV61_List1,
  848.             MainWindowPtr,
  849.             NULL,
  850.             GTLV_Labels, NULL,
  851.             TAG_DONE
  852.         );
  853.     }
  854.  
  855. bye:
  856.     if (IFFHandle)
  857.     {   /* Terminate the IFF transaction with the stream. Free all
  858.          * associated structures. */
  859.         CloseIFF(IFFHandle);
  860.         // Close the stream itself.
  861.         if (IFFHandle->iff_Stream)
  862.         {   Close(IFFHandle->iff_Stream);
  863.         }
  864.         // Free the IFF_File structure itself.
  865.         FreeIFF(IFFHandle);
  866.         IFFHandle = NULL;
  867. }   }
  868.  
  869. AGLOBAL void iff_exit(void)
  870. {   ULONG i;
  871.  
  872.     if (IFFHandle)
  873.     {   /* Terminate the IFF transaction with the stream. Free all
  874.          * associated structures. */
  875.         CloseIFF(IFFHandle);
  876.         // Close the stream itself.
  877.         if (IFFHandle->iff_Stream)
  878.         {   Close(IFFHandle->iff_Stream);
  879.         }
  880.         // Free the IFF_File structure itself.
  881.         FreeIFF(IFFHandle);
  882.         IFFHandle = NULL;
  883.     }
  884.  
  885.     if (List2Nodes)
  886.     {   FreeNameNodes(&List2);
  887.         List2Nodes = FALSE;
  888.     }
  889.     if (List1Nodes)
  890.     {   FreeNameNodes(&List1);
  891.         List1Nodes = NULL;
  892.     }
  893.     for (i = 0; i < items; i++)
  894.     {   if (contents[i].DataPtr)
  895.         {   FreeMem(contents[i].DataPtr, contents[i].bytes);
  896.             contents[i].DataPtr = NULL;
  897.     }   }
  898.     items = 0;
  899. }
  900.  
  901. MODULE void PrintTopChunk(void)
  902. {   struct ContextNode* top;
  903.     short               i;
  904.     char                idbuf[5];
  905.     ULONG               length;
  906.  
  907.     /* Get a pointer to the context node describing the current context. */
  908.     if (!(top = CurrentChunk(IFFHandle)))
  909.         return;
  910.  
  911.     /* Print spaces equivalent to the current nesting depth of chunks
  912.      * processed so far.
  913.      *   This will cause nested chunks to be printed out indented. */
  914.  
  915.     tempstring1[0] = 0;
  916.     if (IFFHandle->iff_Depth > 2)
  917.     {   for (i = IFFHandle->iff_Depth - 2; i--; )
  918.            strcat(tempstring1, " ");
  919.     }
  920.     strcpy(contents[items].name, IDtoStr(top->cn_ID, idbuf));
  921.     contents[items].DataPtr = NULL;
  922.  
  923.     /* Print out the current chunk's ID and size. */
  924.     strcat(tempstring1, IDtoStr(top->cn_ID, idbuf));
  925.     stcl_d(tempstring2, top->cn_Size);
  926.  
  927.     length = IFFXCHARS - strlen(tempstring1) - strlen(tempstring2);
  928.     for (i = 1; i <= length; i++)
  929.     {   strcat(tempstring1, " ");
  930.     }
  931.     strcat(tempstring1, tempstring2);
  932.  
  933.     /* Print the current chunk's type, with a newline. */
  934.     AddNameToTail(&List1, tempstring1);
  935.     list1lines++;
  936.     List1Nodes = TRUE;
  937.  
  938.     if (!strcmp(IDtoStr(top->cn_ID, idbuf), "FORM"))
  939.     {   if (first)
  940.         {   first = FALSE;
  941.             strcpy(queryform, IDtoStr(top->cn_Type, idbuf));
  942.             iffquery();
  943.     }   }
  944.     else
  945.     {   contents[items].bytes = top->cn_Size;
  946.         if (!(contents[items].DataPtr = AllocMem(contents[items].bytes, MEMF_CLEAR)))
  947.         {   rq("Out of memory!");
  948.         }
  949.         if (ReadChunkBytes(IFFHandle, contents[items].DataPtr, contents[items].bytes) < 0)
  950.         {   rq("ReadChunkBytes() failed!");
  951.     }   }
  952.  
  953.     items++;
  954.     if (items > ITEMS)
  955.     {   rq("Too many chunks!");
  956. }   }
  957.  
  958. MODULE void tellchunk(UWORD which)
  959. {   SLONG           svalue;
  960.     ULONG           i, j, uvalue, length, markers, currentpos;
  961.     struct DateTime DateTime;
  962.  
  963.     if (which == (UWORD) ~0)
  964.     {   return;
  965.     }
  966.  
  967.     GT_SetGadgetAttrs
  968.     (   LV61_List2,
  969.         MainWindowPtr,
  970.         NULL,
  971.         GTLV_Labels, (UWORD) ~0,
  972.         TAG_DONE
  973.     );
  974.     if (List2Nodes)
  975.     {   FreeNameNodes(&List2);
  976.         List2Nodes = FALSE;
  977.     }
  978.     NewList(&List2);
  979.  
  980.     known = FALSE;
  981.     List2Nodes = TRUE;
  982.     /* Although it is possible that this function will return with an
  983.     empty List2, remember that it is harmless to call FreeNameNodes on
  984.     a valid, empty List (ie. one which has had NewList() called). */
  985.  
  986.     if (!stricmp(contents[which].name, "FORM"))
  987.     {   chunkdesc("-", TRUE);
  988.     } elif (!stricmp(contents[which].name, "(c) "))
  989.     {   chunkdesc("© Copyright", TRUE);
  990.  
  991.         if (!iff.raw)
  992.         {   strcpy(tempstring1, "© Copyright:        ");
  993.             strcat(tempstring1, contents[which].DataPtr);
  994.             AddNameToTail(&List2, tempstring1);
  995.     }   }
  996.     elif (!stricmp(contents[which].name, "AUTH"))
  997.     {   chunkdesc("Author", TRUE);
  998.  
  999.         if (!iff.raw)
  1000.         {   strcpy(tempstring1, "Author:             ");
  1001.             strcat(tempstring1, contents[which].DataPtr);
  1002.             AddNameToTail(&List2, tempstring1);
  1003.     }   }
  1004.     elif (!stricmp(contents[which].name, "ANNO"))
  1005.     {   chunkdesc("Annotation", TRUE);
  1006.  
  1007.         if (!iff.raw)
  1008.         {   strcpy(tempstring1, "Annotation:         ");
  1009.             strcat(tempstring1, contents[which].DataPtr);
  1010.             AddNameToTail(&List2, tempstring1);
  1011.     }   }
  1012.     elif (!stricmp(contents[which].name, "NAME"))
  1013.     {   chunkdesc("Name", TRUE);
  1014.  
  1015.         if (!iff.raw)
  1016.         {   strcpy(tempstring1, "Name:               ");
  1017.             strcat(tempstring1, contents[which].DataPtr);
  1018.             AddNameToTail(&List2, tempstring1);
  1019.     }   }
  1020.     elif (!stricmp(contents[which].name, "FVER"))
  1021.     {   chunkdesc("AmigaDOS version string", TRUE);
  1022.  
  1023.         if (!iff.raw)
  1024.         {   strcpy(tempstring1, "Version:            ");
  1025.             // bytes 0-5 are "$VER: "
  1026.             strcat(tempstring1, &contents[which].DataPtr[6]);
  1027.             AddNameToTail(&List2, tempstring1);
  1028.     }   }
  1029.     elif
  1030.     (   (!stricmp(queryform, "FTXT") || !stricmp(queryform, "WORD"))
  1031.      && !stricmp(contents[which].name, "FSCC")
  1032.     )
  1033.     {   chunkdesc("Font/style/colour change", TRUE);
  1034.  
  1035.         if (!iff.raw)
  1036.         {
  1037.         strcpy(tempstring1, "Location:            ");
  1038.         uvalue = getuword(contents[which].DataPtr); // UWORD
  1039.         stcl_d(tempstring2, uvalue);
  1040.         strcat(tempstring1, tempstring2);
  1041.         AddNameToTail(&List2, tempstring1);
  1042.  
  1043.         strcpy(tempstring1, "Font number:         ");
  1044.         uvalue = contents[which].DataPtr[2]; // UBYTE
  1045.         stcl_d(tempstring2, uvalue);
  1046.         strcat(tempstring1, tempstring2);
  1047.         AddNameToTail(&List2, tempstring1);
  1048.  
  1049.         strcat(tempstring1, " Style:");
  1050.         AddNameToTail(&List2, tempstring1);
  1051.  
  1052.         strcat(tempstring1, " Underlined?         ");
  1053.         if (contents[which].DataPtr[3] & 1)
  1054.         {   strcat(tempstring1, "Yes");
  1055.         } else strcat(tempstring1, "No");
  1056.         AddNameToTail(&List2, tempstring1);
  1057.  
  1058.         strcat(tempstring1, " Bold?               ");
  1059.         if (contents[which].DataPtr[3] & 2)
  1060.         {   strcat(tempstring1, "Yes");
  1061.         } else strcat(tempstring1, "No");
  1062.         AddNameToTail(&List2, tempstring1);
  1063.  
  1064.         strcat(tempstring1, " Italic?             ");
  1065.         if (contents[which].DataPtr[3] & 4)
  1066.         {   strcat(tempstring1, "Yes");
  1067.         } else strcat(tempstring1, "No");
  1068.         AddNameToTail(&List2, tempstring1);
  1069.  
  1070.             strcat(tempstring1, " Extended?           ");
  1071.             if (contents[which].DataPtr[3] & 8)
  1072.             {   strcat(tempstring1, "Yes");
  1073.             } else strcat(tempstring1, "No");
  1074.             AddNameToTail(&List2, tempstring1);
  1075.  
  1076.             strcat(tempstring1, " ColourFont?         ");
  1077.             if (contents[which].DataPtr[3] & 64)
  1078.             {   strcat(tempstring1, "Yes");
  1079.             } else strcat(tempstring1, "No");
  1080.             AddNameToTail(&List2, tempstring1);
  1081.  
  1082.             strcat(tempstring1, " Tagged?             ");
  1083.             if (contents[which].DataPtr[3] & 128)
  1084.             {   strcat(tempstring1, "Yes");
  1085.             } else strcat(tempstring1, "No");
  1086.             AddNameToTail(&List2, tempstring1);
  1087.  
  1088.             strcpy(tempstring1, "Miscellaneous style: ");
  1089.             if (contents[which].DataPtr[4] == 0)
  1090.             {   strcat(tempstring1, "None");
  1091.             } elif (contents[which].DataPtr[4] == 1)
  1092.             {   strcat(tempstring1, "Superscript");
  1093.             } elif (contents[which].DataPtr[4] == 2)
  1094.             {   strcat(tempstring1, "Subscript");
  1095.             } else
  1096.             {   strcat(tempstring1, "?");
  1097.             }
  1098.             AddNameToTail(&List2, tempstring1);
  1099.  
  1100.             strcpy(tempstring1, "Colour:              ");
  1101.             uvalue = contents[which].DataPtr[5]; // UBYTE
  1102.             stcl_d(tempstring2, uvalue);
  1103.             strcat(tempstring1, tempstring2);
  1104.             AddNameToTail(&List2, tempstring1);
  1105.     }   }
  1106.     elif (!strcmp(queryform, "FTXT"))
  1107.     {   if (!strcmp(contents[which].name, "FONS"))
  1108.         {   chunkdesc("Font specifier", TRUE);
  1109.  
  1110.         if (!iff.raw)
  1111.         {
  1112.             strcpy(tempstring1, "ID number:          ");
  1113.             stcl_d(tempstring2, contents[which].DataPtr[0]);
  1114.             strcat(tempstring1, tempstring2);
  1115.             if (contents[which].DataPtr[0] > 9)
  1116.             {   strcat(tempstring1, " (invalid)");
  1117.             }
  1118.             AddNameToTail(&List2, tempstring1);
  1119.  
  1120.             // Next is a pad byte ([1]).
  1121.  
  1122.             strcpy(tempstring1, "Proportional?       ");
  1123.             uvalue = contents[which].DataPtr[2];
  1124.             if (uvalue == 0)
  1125.             {   strcat(tempstring1, "Unknown");
  1126.             } elif (uvalue == 1)
  1127.             {   strcat(tempstring1, "No");
  1128.             } elif (uvalue == 2)
  1129.             {   strcat(tempstring1, "Yes");
  1130.             } else strcat(tempstring1, "?"); // not the same as `Unknown', of course!
  1131.             AddNameToTail(&List2, tempstring1);
  1132.  
  1133.             strcpy(tempstring1, "Serifs?             ");
  1134.             uvalue = contents[which].DataPtr[3];
  1135.             if (uvalue == 0)
  1136.             {   strcat(tempstring1, "Unknown");
  1137.             } elif (uvalue == 1)
  1138.             {   strcat(tempstring1, "No");
  1139.             } elif (uvalue == 2)
  1140.             {   strcat(tempstring1, "Yes");
  1141.             } else strcat(tempstring1, "?"); // not the same as `Unknown', of course!
  1142.             AddNameToTail(&List2, tempstring1);
  1143.  
  1144.             strcpy(tempstring1, "Font name:          ");
  1145.             strcat(tempstring1, &(contents[which].DataPtr[4]));
  1146.             AddNameToTail(&List2, tempstring1);
  1147.         }   }
  1148.         elif (!strcmp(contents[which].name, "CHRS"))
  1149.         {   chunkdesc("Stream of text", FALSE);
  1150.     }   }
  1151.     elif (!strcmp(queryform, "PREF"))
  1152.     {   if (!strcmp(contents[which].name, "ICTL"))
  1153.         {   chunkdesc("IControl preferences", TRUE);
  1154.  
  1155.         if (!iff.raw)
  1156.         {
  1157.             strcpy(tempstring1, "Verify timeout:         ");
  1158.             uvalue = getuword(&(contents[which].DataPtr[16]));
  1159.             stcl_d(tempstring2, uvalue);
  1160.             strcat(tempstring1, tempstring2);
  1161.             AddNameToTail(&List2, tempstring1);
  1162.  
  1163.             strcpy(tempstring1, "Meta drag mouse event:  ");
  1164.             svalue = getsword(&(contents[which].DataPtr[18]));
  1165.             stcl_d(tempstring2, svalue);
  1166.             strcat(tempstring1, tempstring2);
  1167.             AddNameToTail(&List2, tempstring1);
  1168.  
  1169.             AddNameToTail(&List2, "Flags:");
  1170.             uvalue = getulong(&(contents[which].DataPtr[20]));
  1171.  
  1172.             strcpy(tempstring1, " Coerce colours?        ");
  1173.             if (uvalue & 1) // ICF_COERCE_COLORS
  1174.             {   strcat(tempstring1, "Yes");
  1175.             } else strcat(tempstring1, "No");
  1176.             AddNameToTail(&List2, tempstring1);
  1177.  
  1178.             strcpy(tempstring1, " Coerce interlace?      ");
  1179.             if (uvalue & 2) // ICF_COERCE_LACE
  1180.             {   strcat(tempstring1, "Yes");
  1181.             } else strcat(tempstring1, "No");
  1182.             AddNameToTail(&List2, tempstring1);
  1183.  
  1184.             strcpy(tempstring1, " String gadget filter?  ");
  1185.             if (uvalue & 4) // ICF_STRGAD_FILTER
  1186.             {   strcat(tempstring1, "Yes");
  1187.             } else strcat(tempstring1, "No");
  1188.             AddNameToTail(&List2, tempstring1);
  1189.  
  1190.             strcpy(tempstring1, " Menu snap?             ");
  1191.             if (uvalue & 8) // ICF_MENUSNAP
  1192.             {   strcat(tempstring1, "Yes");
  1193.             } else strcat(tempstring1, "No");
  1194.             AddNameToTail(&List2, tempstring1);
  1195.  
  1196.             strcpy(tempstring1, " Mode promotion?        ");
  1197.             if (uvalue & 16) // ICF_MODEPROMOTE
  1198.             {   strcat(tempstring1, "Yes");
  1199.             } else strcat(tempstring1, "No");
  1200.             AddNameToTail(&List2, tempstring1);
  1201.  
  1202.             strcpy(tempstring1, " Square ratio?          "); // this one is new for OS3.9
  1203.             if (uvalue & 32) // ICF_SQUARE_RATIO
  1204.             {   strcat(tempstring1, "Yes");
  1205.             } else strcat(tempstring1, "No");
  1206.             AddNameToTail(&List2, tempstring1);
  1207.  
  1208.             AddNameToTail(&List2, "Command keys:");
  1209.  
  1210.             strcat(tempstring1, " Workbench to front:    ");
  1211.             stcl_d(tempstring2, contents[which].DataPtr[24]);
  1212.             strcat(tempstring1, tempstring2);
  1213.             AddNameToTail(&List2, tempstring1);
  1214.  
  1215.             strcat(tempstring1, " Front screen to back:  ");
  1216.             stcl_d(tempstring2, contents[which].DataPtr[25]);
  1217.             strcat(tempstring1, tempstring2);
  1218.             AddNameToTail(&List2, tempstring1);
  1219.  
  1220.             strcat(tempstring1, " Requester TRUE:        ");
  1221.             stcl_d(tempstring2, contents[which].DataPtr[26]);
  1222.             strcat(tempstring1, tempstring2);
  1223.             AddNameToTail(&List2, tempstring1);
  1224.  
  1225.             strcat(tempstring1, " Requester FALSE:       ");
  1226.             stcl_d(tempstring2, contents[which].DataPtr[27]);
  1227.             strcat(tempstring1, tempstring2);
  1228.             AddNameToTail(&List2, tempstring1);
  1229.         }   }
  1230.         elif (!strcmp(contents[which].name, "SERL"))
  1231.         {   chunkdesc("Serial preferences", TRUE);
  1232.  
  1233.         if (!iff.raw)
  1234.         {
  1235.             strcpy(tempstring1, "Unit 0 mapping:         ");
  1236.             uvalue = getulong(&(contents[which].DataPtr[12]));
  1237.             stcl_d(tempstring2, uvalue);
  1238.             strcat(tempstring1, tempstring2);
  1239.             AddNameToTail(&List2, tempstring1);
  1240.  
  1241.             strcpy(tempstring1, "Baud rate:              ");
  1242.             uvalue = getulong(&(contents[which].DataPtr[16]));
  1243.             stcl_d(tempstring2, uvalue);
  1244.             strcat(tempstring1, tempstring2);
  1245.             strcat(tempstring1, " bps");
  1246.             AddNameToTail(&List2, tempstring1);
  1247.  
  1248.             strcpy(tempstring1, "Input buffer size:      ");
  1249.             uvalue = getulong(&(contents[which].DataPtr[20]));
  1250.             stcl_d(tempstring2, uvalue);
  1251.             strcat(tempstring1, tempstring2);
  1252.             if (uvalue > 65536)
  1253.             {   strcat(tempstring1, "!");
  1254.             }
  1255.             AddNameToTail(&List2, tempstring1);
  1256.  
  1257.             strcpy(tempstring1, "Output buffer size:     ");
  1258.             uvalue = getulong(&(contents[which].DataPtr[24]));
  1259.             stcl_d(tempstring2, uvalue);
  1260.             strcat(tempstring1, tempstring2);
  1261.             if (uvalue > 65536)
  1262.             {   strcat(tempstring1, "!");
  1263.             }
  1264.             AddNameToTail(&List2, tempstring1);
  1265.  
  1266.             strcpy(tempstring1, "Input handshaking:      ");
  1267.             if (contents[which].DataPtr[28] == 0)
  1268.             {   strcat(tempstring1, "0 (XON)");  // HSHAKE_XON
  1269.             } elif (contents[which].DataPtr[28] == 1)
  1270.             {   strcat(tempstring1, "1 (RTS)");  // HSHAKE_RTS
  1271.             } elif (contents[which].DataPtr[28] == 2)
  1272.             {   strcat(tempstring1, "2 (None)"); // HSHAKE_NONE
  1273.             } else
  1274.             {   strcat(tempstring1, "?");
  1275.             }
  1276.             AddNameToTail(&List2, tempstring1);
  1277.  
  1278.             strcpy(tempstring1, "Output handshaking:     ");
  1279.             if (contents[which].DataPtr[29] == 0)
  1280.             {   strcat(tempstring1, "0 (XON)");  // HSHAKE_XON
  1281.             } elif (contents[which].DataPtr[29] == 1)
  1282.             {   strcat(tempstring1, "1 (RTS)");  // HSHAKE_RTS
  1283.             } elif (contents[which].DataPtr[29] == 2)
  1284.             {   strcat(tempstring1, "2 (None)"); // HSHAKE_NONE
  1285.             } else
  1286.             {   strcat(tempstring1, "?");
  1287.             }
  1288.             AddNameToTail(&List2, tempstring1);
  1289.  
  1290.             strcpy(tempstring1, "Parity:                 ");
  1291.             if (contents[which].DataPtr[30] == 0)
  1292.             {   strcat(tempstring1, "0 (None)");  // PARITY_NONE
  1293.             } elif (contents[which].DataPtr[30] == 1)
  1294.             {   strcat(tempstring1, "1 (Even)");  // PARITY_EVEN
  1295.             } elif (contents[which].DataPtr[30] == 2)
  1296.             {   strcat(tempstring1, "2 (Odd)");   // PARITY_ODD
  1297.             } elif (contents[which].DataPtr[30] == 3)
  1298.             {   strcat(tempstring1, "3 (Mark)");  // PARITY_MARK
  1299.             } elif (contents[which].DataPtr[30] == 4)
  1300.             {   strcat(tempstring1, "4 (Space)"); // PARITY_SPACE
  1301.             } else
  1302.             {   strcat(tempstring1, "?");
  1303.             }
  1304.             AddNameToTail(&List2, tempstring1);
  1305.  
  1306.             strcpy(tempstring1, "I/O bits per character: ");
  1307.             stcl_d(tempstring2, contents[which].DataPtr[31]);
  1308.             strcat(tempstring1, tempstring2);
  1309.             AddNameToTail(&List2, tempstring1);
  1310.  
  1311.             strcpy(tempstring1, "Stop bits:              ");
  1312.             stcl_d(tempstring2, contents[which].DataPtr[32]);
  1313.             strcat(tempstring1, tempstring2);
  1314.             AddNameToTail(&List2, tempstring1);
  1315.         }   }
  1316.         elif (!strcmp(contents[which].name, "ASL "))
  1317.         {   chunkdesc("ASL preferences", TRUE);
  1318.  
  1319.             // 16 reserved bytes at start
  1320.  
  1321.             if (!iff.raw)
  1322.             {   strcpy(tempstring1, "Sort by:                ");
  1323.                 if (contents[which].DataPtr[16] == 0)
  1324.                 {   strcat(tempstring1, "0 (name)");
  1325.                 } elif (contents[which].DataPtr[16] == 1)
  1326.                 {   strcat(tempstring1, "1 (date)");
  1327.                 } elif (contents[which].DataPtr[16] == 2)
  1328.                 {   strcat(tempstring1, "2 (size)");
  1329.                 } else
  1330.                 {   strcat(tempstring1, "?");
  1331.                 }
  1332.                 AddNameToTail(&List2, tempstring1);
  1333.  
  1334.                 strcpy(tempstring1, "Sort drawers:           ");
  1335.                 if (contents[which].DataPtr[17] == 0)
  1336.                 {   strcat(tempstring1, "0 (first)");
  1337.                 } elif (contents[which].DataPtr[17] == 1)
  1338.                 {   strcat(tempstring1, "1 (mix)");
  1339.                 } elif (contents[which].DataPtr[17] == 2)
  1340.                 {   strcat(tempstring1, "2 (last)");
  1341.                 } else
  1342.                 {   strcat(tempstring1, "?");
  1343.                 }
  1344.                 AddNameToTail(&List2, tempstring1);
  1345.  
  1346.                 strcpy(tempstring1, "Sort order:             ");
  1347.                 if (contents[which].DataPtr[18] == 0)
  1348.                 {   strcat(tempstring1, "0 (ascending)");
  1349.                 } elif (contents[which].DataPtr[18] == 1)
  1350.                 {   strcat(tempstring1, "1 (descending)");
  1351.                 } else
  1352.                 {   strcat(tempstring1, "?");
  1353.                 }
  1354.                 AddNameToTail(&List2, tempstring1);
  1355.  
  1356.                 strcpy(tempstring1, "Override?               ");
  1357.                 if (contents[which].DataPtr[19] & 64)
  1358.                 {   strcat(tempstring1, "Yes");
  1359.                 } else
  1360.                 {   strcat(tempstring1, "No");
  1361.                 }
  1362.                 AddNameToTail(&List2, tempstring1);
  1363.  
  1364.                 strcpy(tempstring1, "Relative?               ");
  1365.                 if (contents[which].DataPtr[19] & 16)
  1366.                 {   strcat(tempstring1, "Yes");
  1367.                 } else
  1368.                 {   strcat(tempstring1, "No");
  1369.                 }
  1370.                 AddNameToTail(&List2, tempstring1);
  1371.  
  1372.                 strcpy(tempstring1, "Position:               ");
  1373.                 if (contents[which].DataPtr[19] % 16 == 0)
  1374.                 {   strcat(tempstring1, "0 (default)");
  1375.                 } elif (contents[which].DataPtr[19] % 16 == 1)
  1376.                 {   strcat(tempstring1, "1 (center in window)");
  1377.                 } elif (contents[which].DataPtr[19] % 16 == 2)
  1378.                 {   strcat(tempstring1, "2 (center on screen)");
  1379.                 } elif (contents[which].DataPtr[19] % 16 == 3)
  1380.                 {   strcat(tempstring1, "3 (top left of window)");
  1381.                 } elif (contents[which].DataPtr[19] % 16 == 4)
  1382.                 {   strcat(tempstring1, "4 (top left of screen)");
  1383.                 } elif (contents[which].DataPtr[19] % 16 == 5)
  1384.                 {   strcat(tempstring1, "5 (mouse pointer)");
  1385.                 } else
  1386.                 {   strcat(tempstring1, "?");
  1387.                 }
  1388.                 AddNameToTail(&List2, tempstring1);
  1389.  
  1390.                 strcpy(tempstring1, "Left edge:              ");
  1391.                 svalue = getsword(&(contents[which].DataPtr[20]));
  1392.                 stcl_d(tempstring2, uvalue);
  1393.                 strcat(tempstring1, tempstring2);
  1394.                 AddNameToTail(&List2, tempstring1);
  1395.  
  1396.                 strcpy(tempstring1, "Top edge:               ");
  1397.                 svalue = getsword(&(contents[which].DataPtr[22]));
  1398.                 stcl_d(tempstring2, uvalue);
  1399.                 strcat(tempstring1, tempstring2);
  1400.                 AddNameToTail(&List2, tempstring1);
  1401.  
  1402.                 strcpy(tempstring1, "Relative width:         ");
  1403.                 stcl_d(tempstring2, contents[which].DataPtr[24]);
  1404.                 strcat(tempstring1, tempstring2);
  1405.                 if (contents[which].DataPtr[24] < 25 || contents[which].DataPtr[24] > 100)
  1406.                 {   strcat(tempstring1, "!");
  1407.                 }
  1408.                 strcat(tempstring1, "%");
  1409.                 AddNameToTail(&List2, tempstring1);
  1410.  
  1411.                 strcpy(tempstring1, "Relative height:        ");
  1412.                 stcl_d(tempstring2, contents[which].DataPtr[25]);
  1413.                 strcat(tempstring1, tempstring2);
  1414.                 if (contents[which].DataPtr[25] < 25 || contents[which].DataPtr[25] > 100)
  1415.                 {   strcat(tempstring1, "!");
  1416.                 }
  1417.                 strcat(tempstring1, "%");
  1418.                 AddNameToTail(&List2, tempstring1);
  1419.         }   }
  1420.         elif (!strcmp(contents[which].name, "FONT"))
  1421.         {   chunkdesc("Font preferences", TRUE);
  1422.  
  1423.             // 14 reserved bytes at start
  1424.  
  1425.         if (!iff.raw)
  1426.         {
  1427.             strcpy(tempstring1, "Type:                   ");
  1428.             uvalue = getuword(&(contents[which].DataPtr[14]));
  1429.             if (uvalue == 0)
  1430.             {   strcat(tempstring1, "0 (Workbench)");
  1431.             } elif (uvalue == 1)
  1432.             {   strcat(tempstring1, "1 (system)");
  1433.             } elif (uvalue == 2)
  1434.             {   strcat(tempstring1, "2 (screen)");
  1435.             } else
  1436.             {   strcat(tempstring1, "?");
  1437.             }
  1438.             AddNameToTail(&List2, tempstring1);
  1439.  
  1440.             strcpy(tempstring1, "Front pen:              ");
  1441.             stcl_d(tempstring2, contents[which].DataPtr[16]);
  1442.             strcat(tempstring1, tempstring2);
  1443.             AddNameToTail(&List2, tempstring1);
  1444.  
  1445.             strcpy(tempstring1, "Back pen:               ");
  1446.             stcl_d(tempstring2, contents[which].DataPtr[17]);
  1447.             strcat(tempstring1, tempstring2);
  1448.             AddNameToTail(&List2, tempstring1);
  1449.  
  1450.             strcpy(tempstring1, "Draw mode:              ");
  1451.             if (contents[which].DataPtr[18] == 0) // JAM1
  1452.             {   strcat(tempstring1, "0 (JAM1)");
  1453.             } elif (contents[which].DataPtr[18] == 1) // JAM2
  1454.             {   strcat(tempstring1, "1 (JAM2)");
  1455.             } elif (contents[which].DataPtr[18] == 2) // COMPLEMENT
  1456.             {   strcat(tempstring1, "2 (complement)");
  1457.             } elif (contents[which].DataPtr[18] == 3) // INVERSVID
  1458.             {   strcat(tempstring1, "3 (inverse video)");
  1459.             } else
  1460.             {   strcat(tempstring1, "?");
  1461.             }
  1462.             AddNameToTail(&List2, tempstring1);
  1463.  
  1464.             /* Now we have an undocumented pad byte, necessary for
  1465.             structure alignment purposes. */
  1466.  
  1467.             AddNameToTail(&List2, "Text attributes:");
  1468.  
  1469.             dotextattr(&contents[which].DataPtr[20]);
  1470.  
  1471.             strcpy(tempstring1, "Name:                   ");
  1472.             strcat(tempstring1, &(contents[which].DataPtr[28]));
  1473.             AddNameToTail(&List2, tempstring1);
  1474.         }   }
  1475.         elif (!strcmp(contents[which].name, "INPT"))
  1476.         {   chunkdesc("Input preferences", TRUE);
  1477.  
  1478.             // The first 16 bytes are a keymap, currently ignored
  1479.  
  1480.         if (!iff.raw)
  1481.         {
  1482.             strcpy(tempstring1, "Pointer sensitivity:    ");
  1483.             uvalue = getuword(&(contents[which].DataPtr[16]));
  1484.             stcl_d(tempstring2, uvalue);
  1485.             strcat(tempstring1, tempstring2);
  1486.             strcat(tempstring1, " ticks");
  1487.             AddNameToTail(&List2, tempstring1);
  1488.  
  1489.             AddNameToTail(&List2, "Double-click interval:");
  1490.  
  1491.             strcpy(tempstring1, " Seconds:               ");
  1492.             uvalue = getulong(&(contents[which].DataPtr[18]));
  1493.             stcl_d(tempstring2, uvalue);
  1494.             strcat(tempstring1, tempstring2);
  1495.             AddNameToTail(&List2, tempstring1);
  1496.  
  1497.             strcpy(tempstring1, " Microseconds:          ");
  1498.             uvalue = getulong(&(contents[which].DataPtr[22]));
  1499.             stcl_d(tempstring2, uvalue);
  1500.             strcat(tempstring1, tempstring2);
  1501.             AddNameToTail(&List2, tempstring1);
  1502.  
  1503.             AddNameToTail(&List2, "Key repeat delay:");
  1504.  
  1505.             strcpy(tempstring1, " Seconds:               ");
  1506.             uvalue = getulong(&(contents[which].DataPtr[26]));
  1507.             stcl_d(tempstring2, uvalue);
  1508.             strcat(tempstring1, tempstring2);
  1509.             AddNameToTail(&List2, tempstring1);
  1510.  
  1511.             strcpy(tempstring1, " Microseconds:          ");
  1512.             uvalue = getulong(&(contents[which].DataPtr[30]));
  1513.             stcl_d(tempstring2, uvalue);
  1514.             strcat(tempstring1, tempstring2);
  1515.             AddNameToTail(&List2, tempstring1);
  1516.  
  1517.             AddNameToTail(&List2, "Key repeat speed:");
  1518.  
  1519.             strcpy(tempstring1, " Seconds:               ");
  1520.             uvalue = getulong(&(contents[which].DataPtr[34]));
  1521.             stcl_d(tempstring2, uvalue);
  1522.             strcat(tempstring1, tempstring2);
  1523.             AddNameToTail(&List2, tempstring1);
  1524.  
  1525.             strcpy(tempstring1, " Microseconds:          ");
  1526.             uvalue = getulong(&(contents[which].DataPtr[38]));
  1527.             stcl_d(tempstring2, uvalue);
  1528.             strcat(tempstring1, tempstring2);
  1529.             AddNameToTail(&List2, tempstring1);
  1530.  
  1531.             strcpy(tempstring1, "Mouse acceleration:     ");
  1532.             svalue = getsword(&(contents[which].DataPtr[42]));
  1533.             stcl_d(tempstring2, svalue);
  1534.             strcat(tempstring1, tempstring2);
  1535.             AddNameToTail(&List2, tempstring1);
  1536.         }   }
  1537.         elif (!strcmp(contents[which].name, "OSCN"))
  1538.         {   chunkdesc("Overscan preferences", TRUE);
  1539.  
  1540.         if (!iff.raw)
  1541.         {
  1542.             strcpy(tempstring1, "Magic?                  ");
  1543.             uvalue = getulong(&(contents[which].DataPtr[4]));
  1544.             if (uvalue == 0xFEDCBA89) // OSCAN_MAGIC
  1545.             {   strcat(tempstring1, "Yes");
  1546.             } else
  1547.             {   strcat(tempstring1, "No");
  1548.             }
  1549.             AddNameToTail(&List2, tempstring1);
  1550.  
  1551.             strcpy(tempstring1, "Horizontal start:       ");
  1552.             uvalue = getuword(&(contents[which].DataPtr[8]));
  1553.             stcl_d(tempstring2, uvalue);
  1554.             strcat(tempstring1, tempstring2);
  1555.             AddNameToTail(&List2, tempstring1);
  1556.  
  1557.             strcpy(tempstring1, "Horizontal stop:        ");
  1558.             uvalue = getuword(&(contents[which].DataPtr[10]));
  1559.             stcl_d(tempstring2, uvalue);
  1560.             strcat(tempstring1, tempstring2);
  1561.             AddNameToTail(&List2, tempstring1);
  1562.  
  1563.             strcpy(tempstring1, "Vertical start:         ");
  1564.             uvalue = getuword(&(contents[which].DataPtr[12]));
  1565.             stcl_d(tempstring2, uvalue);
  1566.             strcat(tempstring1, tempstring2);
  1567.             AddNameToTail(&List2, tempstring1);
  1568.  
  1569.             strcpy(tempstring1, "Vertical stop:          ");
  1570.             uvalue = getuword(&(contents[which].DataPtr[14]));
  1571.             stcl_d(tempstring2, uvalue);
  1572.             strcat(tempstring1, tempstring2);
  1573.             AddNameToTail(&List2, tempstring1);
  1574.  
  1575.             strcpy(tempstring1, "DisplayID:              ");
  1576.             uvalue = getulong(&(contents[which].DataPtr[16]));
  1577.             stcl_d(tempstring2, uvalue);
  1578.             strcat(tempstring1, tempstring2);
  1579.             AddNameToTail(&List2, tempstring1);
  1580.  
  1581.             strcpy(tempstring1, "View offset:            ");
  1582.             svalue = getsword(&(contents[which].DataPtr[20]));
  1583.             stcl_d(tempstring2, svalue);
  1584.             strcat(tempstring1, tempstring2);
  1585.             strcat(tempstring1, ",");
  1586.             svalue = getsword(&(contents[which].DataPtr[22]));
  1587.             stcl_d(tempstring2, svalue);
  1588.             strcat(tempstring1, tempstring2);
  1589.             AddNameToTail(&List2, tempstring1);
  1590.  
  1591.             strcpy(tempstring1, "Text overscan size:     ");
  1592.             svalue = getsword(&(contents[which].DataPtr[24]));
  1593.             stcl_d(tempstring2, svalue);
  1594.             strcat(tempstring1, tempstring2);
  1595.             strcat(tempstring1, ",");
  1596.             svalue = getsword(&(contents[which].DataPtr[26]));
  1597.             stcl_d(tempstring2, svalue);
  1598.             strcat(tempstring1, tempstring2);
  1599.             AddNameToTail(&List2, tempstring1);
  1600.  
  1601.             AddNameToTail(&List2, "Standard overscan size:");
  1602.  
  1603.             strcpy(tempstring1, " Top-left corner:       ");
  1604.             svalue = getsword(&(contents[which].DataPtr[28]));
  1605.             stcl_d(tempstring2, svalue);
  1606.             strcat(tempstring1, tempstring2);
  1607.             strcat(tempstring1, ",");
  1608.             svalue = getsword(&(contents[which].DataPtr[30]));
  1609.             stcl_d(tempstring2, svalue);
  1610.             strcat(tempstring1, tempstring2);
  1611.             AddNameToTail(&List2, tempstring1);
  1612.  
  1613.             strcpy(tempstring1, " Bottom-right corner:   ");
  1614.             svalue = getsword(&(contents[which].DataPtr[32]));
  1615.             stcl_d(tempstring2, svalue);
  1616.             strcat(tempstring1, tempstring2);
  1617.             strcat(tempstring1, ",");
  1618.             svalue = getsword(&(contents[which].DataPtr[34]));
  1619.             stcl_d(tempstring2, svalue);
  1620.             strcat(tempstring1, tempstring2);
  1621.             AddNameToTail(&List2, tempstring1);
  1622.         }   }
  1623.         elif (!strcmp(contents[which].name, "SCRM"))
  1624.         {   chunkdesc("Screen mode preferences", TRUE);
  1625.  
  1626.         if (!iff.raw)
  1627.         {
  1628.             strcpy(tempstring1, "DisplayID:              ");
  1629.             uvalue = getulong(&(contents[which].DataPtr[16]));
  1630.             stcl_d(tempstring2, uvalue);
  1631.             strcat(tempstring1, tempstring2);
  1632.             AddNameToTail(&List2, tempstring1);
  1633.  
  1634.             strcpy(tempstring1, "Screen width:           ");
  1635.             uvalue = getuword(&(contents[which].DataPtr[20]));
  1636.             stcl_d(tempstring2, uvalue);
  1637.             strcat(tempstring1, tempstring2);
  1638.             AddNameToTail(&List2, tempstring1);
  1639.  
  1640.             strcpy(tempstring1, "Screen height:          ");
  1641.             uvalue = getuword(&(contents[which].DataPtr[22]));
  1642.             stcl_d(tempstring2, uvalue);
  1643.             strcat(tempstring1, tempstring2);
  1644.             AddNameToTail(&List2, tempstring1);
  1645.  
  1646.             strcpy(tempstring1, "Screen depth:           ");
  1647.             uvalue = getuword(&(contents[which].DataPtr[24]));
  1648.             stcl_d(tempstring2, uvalue);
  1649.             strcat(tempstring1, tempstring2);
  1650.             AddNameToTail(&List2, tempstring1);
  1651.  
  1652.             strcpy(tempstring1, "Autoscroll?             ");
  1653.             uvalue = getuword(&(contents[which].DataPtr[26]));
  1654.             if (uvalue & 1) // SMB_AUTOSCROLL
  1655.             {   strcat(tempstring1, "Yes");
  1656.             } else
  1657.             {   strcat(tempstring1, "No");
  1658.             }
  1659.             AddNameToTail(&List2, tempstring1);
  1660.         }   }
  1661.         elif (!strcmp(contents[which].name, "PSPD"))
  1662.         {   chunkdesc("PostScript printer preferences", TRUE);
  1663.  
  1664.         if (!iff.raw)
  1665.         {   AddNameToTail(&List2, "Global attributes:");
  1666.  
  1667.             strcpy(tempstring1, " Driver mode:           ");
  1668.             if (contents[which].DataPtr[16] == 0) // DM_POSTSCRIPT
  1669.             {   strcat(tempstring1, "0 (PostScript)");
  1670.             } elif (contents[which].DataPtr[16] == 1) // DM_PASSTHROUGH
  1671.             {   strcat(tempstring1, "1 (pass through)");
  1672.             } else
  1673.             {   strcat(tempstring1, "?");
  1674.             }
  1675.             AddNameToTail(&List2, tempstring1);
  1676.  
  1677.             strcpy(tempstring1, " Paper format:          ");
  1678.             if (contents[which].DataPtr[17] == 0) // PF_USLETTER
  1679.             {   strcat(tempstring1, "0 (US Letter)");
  1680.             } elif (contents[which].DataPtr[17] == 1) // PF_USLEGAL
  1681.             {   strcat(tempstring1, "1 (US Legal)");
  1682.             } elif (contents[which].DataPtr[17] == 2) // PF_A4
  1683.             {   strcat(tempstring1, "2 (A4)");
  1684.             } elif (contents[which].DataPtr[17] == 3) // PF_CUSTOM
  1685.             {   strcat(tempstring1, "3 (custom)");
  1686.             } else
  1687.             {   strcat(tempstring1, "?");
  1688.             }
  1689.             AddNameToTail(&List2, tempstring1);
  1690.  
  1691.             // now two reserved bytes
  1692.  
  1693.             strcpy(tempstring1, " Copies:                ");
  1694.             svalue = getslong(&(contents[which].DataPtr[20]));
  1695.             stcl_d(tempstring2, svalue);
  1696.             strcat(tempstring1, tempstring2);
  1697.             AddNameToTail(&List2, tempstring1);
  1698.  
  1699.             strcpy(tempstring1, " Paper width:           ");
  1700.             svalue = getslong(&(contents[which].DataPtr[24]));
  1701.             stcl_d(tempstring2, svalue);
  1702.             strcat(tempstring1, tempstring2);
  1703.             strcat(tempstring1, " millipoints");
  1704.             AddNameToTail(&List2, tempstring1);
  1705.  
  1706.             strcpy(tempstring1, " Paper height:          ");
  1707.             svalue = getslong(&(contents[which].DataPtr[28]));
  1708.             stcl_d(tempstring2, svalue);
  1709.             strcat(tempstring1, tempstring2);
  1710.             strcat(tempstring1, " millipoints");
  1711.             AddNameToTail(&List2, tempstring1);
  1712.  
  1713.             strcpy(tempstring1, " Horizontal DPI:        ");
  1714.             svalue = getslong(&(contents[which].DataPtr[32]));
  1715.             stcl_d(tempstring2, svalue);
  1716.             strcat(tempstring1, tempstring2);
  1717.             strcat(tempstring1, " millipoints");
  1718.             AddNameToTail(&List2, tempstring1);
  1719.  
  1720.             strcpy(tempstring1, " Vertical DPI:          ");
  1721.             svalue = getslong(&(contents[which].DataPtr[36]));
  1722.             stcl_d(tempstring2, svalue);
  1723.             strcat(tempstring1, tempstring2);
  1724.             strcat(tempstring1, " millipoints");
  1725.             AddNameToTail(&List2, tempstring1);
  1726.  
  1727.             AddNameToTail(&List2, "Text options:");
  1728.  
  1729.             strcpy(tempstring1, " Font:                  ");
  1730.             if (contents[which].DataPtr[40] == 0)
  1731.             {   strcat(tempstring1, "0 (Courier)");
  1732.             } elif (contents[which].DataPtr[40] == 1)
  1733.             {   strcat(tempstring1, "1 (Times)");
  1734.             } elif (contents[which].DataPtr[40] == 2)
  1735.             {   strcat(tempstring1, "2 (Helvetica)");
  1736.             } elif (contents[which].DataPtr[40] == 3)
  1737.             {   strcat(tempstring1, "3 (Helvetica Narrow)");
  1738.             } elif (contents[which].DataPtr[40] == 4)
  1739.             {   strcat(tempstring1, "4 (Avant Garde)");
  1740.             } elif (contents[which].DataPtr[40] == 5)
  1741.             {   strcat(tempstring1, "5 (Bookman)");
  1742.             } elif (contents[which].DataPtr[40] == 6)
  1743.             {   strcat(tempstring1, "6 (New Century)");
  1744.             } elif (contents[which].DataPtr[40] == 7)
  1745.             {   strcat(tempstring1, "7 (Palantino)");
  1746.             } elif (contents[which].DataPtr[40] == 8)
  1747.             {   strcat(tempstring1, "8 (Zapf Chancery)");
  1748.             } else
  1749.             {   strcat(tempstring1, "?");
  1750.             }
  1751.             AddNameToTail(&List2, tempstring1);
  1752.  
  1753.             strcpy(tempstring1, " Pitch:                 ");
  1754.             if (contents[which].DataPtr[41] == 0)
  1755.             {   strcat(tempstring1, "0 (normal)");
  1756.             } elif (contents[which].DataPtr[41] == 1)
  1757.             {   strcat(tempstring1, "1 (compressed)");
  1758.             } elif (contents[which].DataPtr[41] == 2)
  1759.             {   strcat(tempstring1, "2 (expanded)");
  1760.             } else
  1761.             {   strcat(tempstring1, "?");
  1762.             }
  1763.             AddNameToTail(&List2, tempstring1);
  1764.  
  1765.             strcpy(tempstring1, " Orientation:           ");
  1766.             if (contents[which].DataPtr[42] == 0) // ORIENT_PORTRAIT
  1767.             {   strcat(tempstring1, "0 (portrait)");
  1768.             } elif (contents[which].DataPtr[42] == 1) // ORIENT_LANDSCAPE
  1769.             {   strcat(tempstring1, "1 (landscape)");
  1770.             } else
  1771.             {   strcat(tempstring1, "?");
  1772.             }
  1773.             AddNameToTail(&List2, tempstring1);
  1774.  
  1775.             strcpy(tempstring1, " Tab stops:             ");
  1776.             if (contents[which].DataPtr[43] == 0) // TAB_4
  1777.             {   strcat(tempstring1, "0 (4 characters)");
  1778.             } elif (contents[which].DataPtr[43] == 1) // TAB_8
  1779.             {   strcat(tempstring1, "1 (8 characters)");
  1780.             } elif (contents[which].DataPtr[43] == 2) // TAB_QUART
  1781.             {   strcat(tempstring1, "2 (quarter-inch)");
  1782.             } elif (contents[which].DataPtr[43] == 3) // TAB_HALF
  1783.             {   strcat(tempstring1, "3 (half-inch)");
  1784.             } elif (contents[which].DataPtr[43] == 4) // TAB_INCH
  1785.             {   strcat(tempstring1, "4 (inch)");
  1786.             } else
  1787.             {   strcat(tempstring1, "?");
  1788.             }
  1789.             AddNameToTail(&List2, tempstring1);
  1790.  
  1791.             // now eight reserved bytes
  1792.  
  1793.             AddNameToTail(&List2, "Text dimensions:");
  1794.  
  1795.             strcpy(tempstring1, " Left margin:           ");
  1796.             svalue = getslong(&(contents[which].DataPtr[52]));
  1797.             stcl_d(tempstring2, svalue);
  1798.             strcat(tempstring1, tempstring2);
  1799.             strcat(tempstring1, " millipoints");
  1800.             AddNameToTail(&List2, tempstring1);
  1801.  
  1802.             strcpy(tempstring1, " Right margin:          ");
  1803.             svalue = getslong(&(contents[which].DataPtr[56]));
  1804.             stcl_d(tempstring2, svalue);
  1805.             strcat(tempstring1, tempstring2);
  1806.             strcat(tempstring1, " millipoints");
  1807.             AddNameToTail(&List2, tempstring1);
  1808.  
  1809.             strcpy(tempstring1, " Top margin:            ");
  1810.             svalue = getslong(&(contents[which].DataPtr[60]));
  1811.             stcl_d(tempstring2, svalue);
  1812.             strcat(tempstring1, tempstring2);
  1813.             strcat(tempstring1, " millipoints");
  1814.             AddNameToTail(&List2, tempstring1);
  1815.  
  1816.             strcpy(tempstring1, " Bottom margin:         ");
  1817.             svalue = getslong(&(contents[which].DataPtr[64]));
  1818.             stcl_d(tempstring2, svalue);
  1819.             strcat(tempstring1, tempstring2);
  1820.             strcat(tempstring1, " millipoints");
  1821.             AddNameToTail(&List2, tempstring1);
  1822.  
  1823.             strcpy(tempstring1, " Font size:             ");
  1824.             svalue = getslong(&(contents[which].DataPtr[68]));
  1825.             stcl_d(tempstring2, svalue);
  1826.             strcat(tempstring1, tempstring2);
  1827.             strcat(tempstring1, " millipoints");
  1828.             AddNameToTail(&List2, tempstring1);
  1829.  
  1830.             strcpy(tempstring1, " Leading:               ");
  1831.             svalue = getslong(&(contents[which].DataPtr[72]));
  1832.             stcl_d(tempstring2, svalue);
  1833.             strcat(tempstring1, tempstring2);
  1834.             strcat(tempstring1, " millipoints");
  1835.             AddNameToTail(&List2, tempstring1);
  1836.  
  1837.             // now eight reserved bytes
  1838.  
  1839.             AddNameToTail(&List2, "Graphics options:");
  1840.  
  1841.             strcpy(tempstring1, " Left edge:             ");
  1842.             svalue = getslong(&(contents[which].DataPtr[80]));
  1843.             stcl_d(tempstring2, svalue);
  1844.             strcat(tempstring1, tempstring2);
  1845.             strcat(tempstring1, " millipoints");
  1846.             AddNameToTail(&List2, tempstring1);
  1847.  
  1848.             strcpy(tempstring1, " Top edge:              ");
  1849.             svalue = getslong(&(contents[which].DataPtr[84]));
  1850.             stcl_d(tempstring2, svalue);
  1851.             strcat(tempstring1, tempstring2);
  1852.             strcat(tempstring1, " millipoints");
  1853.             AddNameToTail(&List2, tempstring1);
  1854.  
  1855.             strcpy(tempstring1, " Width:                 ");
  1856.             svalue = getslong(&(contents[which].DataPtr[88]));
  1857.             stcl_d(tempstring2, svalue);
  1858.             strcat(tempstring1, tempstring2);
  1859.             strcat(tempstring1, " millipoints");
  1860.             AddNameToTail(&List2, tempstring1);
  1861.  
  1862.             strcpy(tempstring1, " Height:                ");
  1863.             svalue = getslong(&(contents[which].DataPtr[92]));
  1864.             stcl_d(tempstring2, svalue);
  1865.             strcat(tempstring1, tempstring2);
  1866.             strcat(tempstring1, " millipoints");
  1867.             AddNameToTail(&List2, tempstring1);
  1868.  
  1869.             strcpy(tempstring1, " Image:                 ");
  1870.             if (contents[which].DataPtr[96] == 0) // IM_POSITIVE
  1871.             {   strcat(tempstring1, "0 (positive)");
  1872.             } elif (contents[which].DataPtr[96] == 1) // IM_NEGATIVE
  1873.             {   strcat(tempstring1, "1 (negative)");
  1874.             } else
  1875.             {   strcat(tempstring1, "?");
  1876.             }
  1877.             AddNameToTail(&List2, tempstring1);
  1878.  
  1879.             strcpy(tempstring1, " Shading:               ");
  1880.             if (contents[which].DataPtr[97] == 0) // SHAD_BW
  1881.             {   strcat(tempstring1, "0 (black and white)");
  1882.             } elif (contents[which].DataPtr[97] == 1) // SHAD_GREYSCALE
  1883.             {   strcat(tempstring1, "1 (greyscale)");
  1884.             } elif (contents[which].DataPtr[97] == 2) // SHAD_COLOR
  1885.             {   strcat(tempstring1, "2 (colour)");
  1886.             } else
  1887.             {   strcat(tempstring1, "?");
  1888.             }
  1889.             AddNameToTail(&List2, tempstring1);
  1890.  
  1891.             strcpy(tempstring1, " Dithering:             ");
  1892.             if (contents[which].DataPtr[98] == 0) // DITH_DEFAULT
  1893.             {   strcat(tempstring1, "0 (default)");
  1894.             } elif (contents[which].DataPtr[98] == 1) // DITH_DOTTY
  1895.             {   strcat(tempstring1, "1 (dotty)");
  1896.             } elif (contents[which].DataPtr[98] == 2) // DITH_VERT
  1897.             {   strcat(tempstring1, "2 (vertical)");
  1898.             } elif (contents[which].DataPtr[98] == 3) // DITH_HORIZ
  1899.             {   strcat(tempstring1, "3 (horizontal)");
  1900.             } elif (contents[which].DataPtr[98] == 4) // DITH_DIAG
  1901.             {   strcat(tempstring1, "4 (diagonal)");
  1902.             } else
  1903.             {   strcat(tempstring1, "?");
  1904.             }
  1905.             AddNameToTail(&List2, tempstring1);
  1906.  
  1907.             // now nine reserved bytes
  1908.  
  1909.             AddNameToTail(&List2, "Graphics scaling:");
  1910.  
  1911.             strcpy(tempstring1, " Aspect:                ");
  1912.             if (contents[which].DataPtr[108] == 0) // ASP_HORIZ
  1913.             {   strcat(tempstring1, "0 (horizontal)");
  1914.             } elif (contents[which].DataPtr[108] == 1) // ASP_VERT
  1915.             {   strcat(tempstring1, "1 (vertical)");
  1916.             } else
  1917.             {   strcat(tempstring1, "?");
  1918.             }
  1919.             AddNameToTail(&List2, tempstring1);
  1920.  
  1921.             strcpy(tempstring1, " Scaling type:          ");
  1922.             if (contents[which].DataPtr[109] == 0) // ST_ASPECT_ASIS
  1923.             {   strcat(tempstring1, "0 (aspect as is)");
  1924.             } elif (contents[which].DataPtr[109] == 1) // ST_ASPECT_WIDE
  1925.             {   strcat(tempstring1, "1 (aspect wide)");
  1926.             } elif (contents[which].DataPtr[109] == 2) // ST_ASPECT_TALL
  1927.             {   strcat(tempstring1, "2 (aspect tall)");
  1928.             } elif (contents[which].DataPtr[109] == 3) // ST_ASPECT_BOTH
  1929.             {   strcat(tempstring1, "3 (aspect both)");
  1930.             } elif (contents[which].DataPtr[109] == 4) // ST_FITS_WIDE
  1931.             {   strcat(tempstring1, "4 (fits wide)");
  1932.             } elif (contents[which].DataPtr[109] == 5) // ST_FITS_TALL
  1933.             {   strcat(tempstring1, "5 (fits tall)");
  1934.             } elif (contents[which].DataPtr[109] == 6) // ST_FITS_BOTH
  1935.             {   strcat(tempstring1, "6 (fits both)");
  1936.             } else
  1937.             {   strcat(tempstring1, "?");
  1938.             }
  1939.             AddNameToTail(&List2, tempstring1);
  1940.  
  1941.             // now one reserved byte
  1942.  
  1943.             strcpy(tempstring1, " Centering:             ");
  1944.             if (contents[which].DataPtr[111] == 0) // CENT_NONE
  1945.             {   strcat(tempstring1, "0 (none)");
  1946.             } elif (contents[which].DataPtr[111] == 1) // CENT_HORIZ
  1947.             {   strcat(tempstring1, "1 (horizontal)");
  1948.             } elif (contents[which].DataPtr[111] == 2) // CENT_VERT
  1949.             {   strcat(tempstring1, "2 (vertical)");
  1950.             } elif (contents[which].DataPtr[111] == 3) // CENT_BOTH
  1951.             {   strcat(tempstring1, "3 (both)");
  1952.             } else
  1953.             {   strcat(tempstring1, "?");
  1954.             }
  1955.             AddNameToTail(&List2, tempstring1);
  1956.         }   }
  1957.         elif (!strcmp(contents[which].name, "PGFX"))
  1958.         {   chunkdesc("Printer graphics preferences", TRUE);
  1959.  
  1960.         if (!iff.raw)
  1961.         {
  1962.             strcpy(tempstring1, "Aspect:                 ");
  1963.             uvalue = getuword(&(contents[which].DataPtr[16]));
  1964.             if (uvalue == 0) // PA_HORIZONTAL
  1965.             {   strcat(tempstring1, "0 (horizontal)");
  1966.             } elif (uvalue == 1) // PA_VERTICAL
  1967.             {   strcat(tempstring1, "1 (vertical)");
  1968.             } else
  1969.             {   strcat(tempstring1, "?");
  1970.             }
  1971.             AddNameToTail(&List2, tempstring1);
  1972.  
  1973.             strcpy(tempstring1, "Shading:                ");
  1974.             uvalue = getuword(&(contents[which].DataPtr[18]));
  1975.             if (uvalue == 0) // PS_BW
  1976.             {   strcat(tempstring1, "0 (black and white)");
  1977.             } elif (uvalue == 1) // PS_GREYSCALE
  1978.             {   strcat(tempstring1, "1 (greyscale 1)");
  1979.             } elif (uvalue == 2) // PS_COLOR
  1980.             {   strcat(tempstring1, "2 (colour)");
  1981.             } elif (uvalue == 3) // PS_GREY_SCALE2
  1982.             {   strcat(tempstring1, "3 (greyscale 2)");
  1983.             } else
  1984.             {   strcat(tempstring1, "?");
  1985.             }
  1986.             AddNameToTail(&List2, tempstring1);
  1987.  
  1988.             strcpy(tempstring1, "Image:                  ");
  1989.             uvalue = getuword(&(contents[which].DataPtr[20]));
  1990.             if (uvalue == 0) // PI_POSITIVE
  1991.             {   strcat(tempstring1, "0 (positive)");
  1992.             } elif (uvalue == 1) // PI_NEGATIVE
  1993.             {   strcat(tempstring1, "1 (negative)");
  1994.             } else
  1995.             {   strcat(tempstring1, "?");
  1996.             }
  1997.             AddNameToTail(&List2, tempstring1);
  1998.  
  1999.             strcpy(tempstring1, "Threshold:              ");
  2000.             svalue = getsword(&(contents[which].DataPtr[22]));
  2001.             stcl_d(tempstring2, svalue);
  2002.             strcat(tempstring1, tempstring2);
  2003.             AddNameToTail(&List2, tempstring1);
  2004.  
  2005.             AddNameToTail(&List2, "Colour correction:");
  2006.  
  2007.             strcpy(tempstring1, " Red?                   ");
  2008.             if (contents[which].DataPtr[24] & 1) // PCCF_RED
  2009.             {   strcat(tempstring1, "Yes");
  2010.             } else
  2011.             {   strcat(tempstring1, "No");
  2012.             }
  2013.             AddNameToTail(&List2, tempstring1);
  2014.  
  2015.             strcpy(tempstring1, " Green?                 ");
  2016.             if (contents[which].DataPtr[24] & 2) // PCCF_GREEN
  2017.             {   strcat(tempstring1, "Yes");
  2018.             } else
  2019.             {   strcat(tempstring1, "No");
  2020.             }
  2021.             AddNameToTail(&List2, tempstring1);
  2022.  
  2023.             strcpy(tempstring1, " Blue?                  ");
  2024.             if (contents[which].DataPtr[24] & 4) // PCCF_BLUE
  2025.             {   strcat(tempstring1, "Yes");
  2026.             } else
  2027.             {   strcat(tempstring1, "No");
  2028.             }
  2029.             AddNameToTail(&List2, tempstring1);
  2030.  
  2031.             strcpy(tempstring1, "Dimensions:             ");
  2032.             if (contents[which].DataPtr[25] == 0) // PD_IGNORE
  2033.             {   strcat(tempstring1, "0 (ignore)");
  2034.             } elif (contents[which].DataPtr[25] == 1) // PD_BOUNDED
  2035.             {   strcat(tempstring1, "1 (bounded)");
  2036.             } elif (contents[which].DataPtr[25] == 2) // PD_ABSOLUTE
  2037.             {   strcat(tempstring1, "2 (absolute)");
  2038.             } elif (contents[which].DataPtr[25] == 3) // PD_PIXEL
  2039.             {   strcat(tempstring1, "3 (printer pixels)");
  2040.             } elif (contents[which].DataPtr[25] == 4) // PD_MULTIPLY
  2041.             {   strcat(tempstring1, "4 (multiply)");
  2042.             } else
  2043.             {   strcat(tempstring1, "?");
  2044.             }
  2045.             AddNameToTail(&List2, tempstring1);
  2046.  
  2047.             strcpy(tempstring1, "Dithering:              ");
  2048.             if (contents[which].DataPtr[26] == 0) // PD_ORDERED
  2049.             {   strcat(tempstring1, "0 (ordered)");
  2050.             } elif (contents[which].DataPtr[26] == 1) // PD_HALFTONE
  2051.             {   strcat(tempstring1, "1 (halftone)");
  2052.             } elif (contents[which].DataPtr[26] == 2) // PD_FLOYD
  2053.             {   strcat(tempstring1, "2 (Floyd-Steinberg)");
  2054.             } else
  2055.             {   strcat(tempstring1, "?");
  2056.             }
  2057.             AddNameToTail(&List2, tempstring1);
  2058.  
  2059.             strcpy(tempstring1, "Flags:");
  2060.             uvalue = getuword(&(contents[which].DataPtr[27]));
  2061.  
  2062.             strcpy(tempstring1, " Centre image?          ");
  2063.             if (uvalue & 1) // PGFF_CENTER_IMAGE
  2064.             {   strcat(tempstring1, "Yes");
  2065.             } else
  2066.             {   strcat(tempstring1, "No");
  2067.             }
  2068.             AddNameToTail(&List2, tempstring1);
  2069.  
  2070.             strcpy(tempstring1, " Integer scaling?       ");
  2071.             if (uvalue & 2) // PGFF_INTEGER_SCALING
  2072.             {   strcat(tempstring1, "Yes");
  2073.             } else
  2074.             {   strcat(tempstring1, "No");
  2075.             }
  2076.             AddNameToTail(&List2, tempstring1);
  2077.  
  2078.             strcpy(tempstring1, " Antialiasing?          ");
  2079.             if (uvalue & 4) // PGFF_ANTI_ALIAS
  2080.             {   strcat(tempstring1, "Yes");
  2081.             } else
  2082.             {   strcat(tempstring1, "No");
  2083.             }
  2084.             AddNameToTail(&List2, tempstring1);
  2085.  
  2086.             strcpy(tempstring1, "Print density:          ");
  2087.             stcl_d(tempstring2, contents[which].DataPtr[29]);
  2088.             strcat(tempstring1, tempstring2);
  2089.             if (contents[which].DataPtr[29] < 1 || contents[which].DataPtr[29] > 7)
  2090.             {   strcat(tempstring1, "!");
  2091.             }
  2092.             AddNameToTail(&List2, tempstring1);
  2093.  
  2094.             strcpy(tempstring1, "Maximum width:          ");
  2095.             uvalue = getuword(&(contents[which].DataPtr[30]));
  2096.             stcl_d(tempstring2, uvalue);
  2097.             strcat(tempstring1, tempstring2);
  2098.             AddNameToTail(&List2, tempstring1);
  2099.  
  2100.             strcpy(tempstring1, "Maximum height:         ");
  2101.             uvalue = getuword(&(contents[which].DataPtr[32]));
  2102.             stcl_d(tempstring2, uvalue);
  2103.             strcat(tempstring1, tempstring2);
  2104.             AddNameToTail(&List2, tempstring1);
  2105.  
  2106.             strcpy(tempstring1, "Offset:                 ");
  2107.             stcl_d(tempstring2, contents[which].DataPtr[34]);
  2108.             strcat(tempstring1, tempstring2);
  2109.             strcat(tempstring1, ",");
  2110.             stcl_d(tempstring2, contents[which].DataPtr[35]);
  2111.             strcat(tempstring1, tempstring2);
  2112.             AddNameToTail(&List2, tempstring1);
  2113.         }   }
  2114.         elif (!strcmp(contents[which].name, "PTXT"))
  2115.         {   chunkdesc("Printer text preferences", TRUE);
  2116.  
  2117.         if (!iff.raw)
  2118.         {
  2119.             strcpy(tempstring1, "Driver filename:        ");
  2120.             strcat(tempstring1, &(contents[which].DataPtr[16]));
  2121.             // 32-character field, so it doesn't need truncation
  2122.             AddNameToTail(&List2, tempstring1);
  2123.  
  2124.             strcpy(tempstring1, "Port:                   ");
  2125.             if (contents[which].DataPtr[48] == 0) // PP_PARALLEL
  2126.             {   strcat(tempstring1, "0 (parallel)");
  2127.             } elif (contents[which].DataPtr[48] == 1) // PP_SERIAL
  2128.             {   strcat(tempstring1, "1 (serial)");
  2129.             } else
  2130.             {   strcat(tempstring1, "?");
  2131.             }
  2132.             AddNameToTail(&List2, tempstring1);
  2133.  
  2134.             strcpy(tempstring1, "Paper type:             ");
  2135.             uvalue = getuword(&(contents[which].DataPtr[49]));
  2136.             if (uvalue == 0) // PT_FANFOLD
  2137.             {   strcat(tempstring1, "0 (fanfold)");
  2138.             } elif (uvalue == 1) // PP_SINGLE
  2139.             {   strcat(tempstring1, "1 (single sheet)");
  2140.             } else
  2141.             {   strcat(tempstring1, "?");
  2142.             }
  2143.             AddNameToTail(&List2, tempstring1);
  2144.  
  2145.             strcpy(tempstring1, "Paper size:             ");
  2146.             uvalue = getuword(&(contents[which].DataPtr[51]));
  2147.             if (uvalue == 0) // PS_US_LETTER
  2148.             {   strcat(tempstring1, "0 (US Letter)");
  2149.             } elif (uvalue == 1) // PS_US_LEGAL
  2150.             {   strcat(tempstring1, "1 (US Legal)");
  2151.             } elif (uvalue == 2) // PS_N_TRACTOR
  2152.             {   strcat(tempstring1, "2 (narrow tractor)");
  2153.             } elif (uvalue == 3) // PS_W_TRACTOR
  2154.             {   strcat(tempstring1, "3 (wide tractor)");
  2155.             } elif (uvalue == 4) // PS_CUSTOM
  2156.             {   strcat(tempstring1, "4 (custom)");
  2157.             } elif (uvalue == 5) // PS_EURO_A0
  2158.             {   strcat(tempstring1, "5 (A0: 841x1189mm)");
  2159.             } elif (uvalue == 6) // PS_EURO_A1
  2160.             {   strcat(tempstring1, "6 (A1: 594x841mm)");
  2161.             } elif (uvalue == 7) // PS_EURO_A2
  2162.             {   strcat(tempstring1, "7 (A2: 420x594mm)");
  2163.             } elif (uvalue == 8) // PS_EURO_A3
  2164.             {   strcat(tempstring1, "8 (A3: 297x420mm)");
  2165.             } elif (uvalue == 9) // PS_EURO_A4
  2166.             {   strcat(tempstring1, "9 (A4: 210x297mm)");
  2167.             } elif (uvalue == 10) // PS_EURO_A5
  2168.             {   strcat(tempstring1, "10 (A5: 148x210mm)");
  2169.             } elif (uvalue == 11) // PS_EURO_A6
  2170.             {   strcat(tempstring1, "11 (A6: 105x148mm)");
  2171.             } elif (uvalue == 12) // PS_EURO_A7
  2172.             {   strcat(tempstring1, "12 (A7: 74x105mm)");
  2173.             } elif (uvalue == 13) // PS_EURO_A8
  2174.             {   strcat(tempstring1, "13 (A8: 52x74mm)");
  2175.             } else
  2176.             {   strcat(tempstring1, "?");
  2177.             }
  2178.             AddNameToTail(&List2, tempstring1);
  2179.  
  2180.             strcpy(tempstring1, "Paper length:           ");
  2181.             uvalue = getuword(&(contents[which].DataPtr[53]));
  2182.             stcl_d(tempstring2, uvalue);
  2183.             strcat(tempstring1, tempstring2);
  2184.             strcat(tempstring1, " lines");
  2185.             AddNameToTail(&List2, tempstring1);
  2186.  
  2187.             strcpy(tempstring1, "Pitch:                  ");
  2188.             uvalue = getuword(&(contents[which].DataPtr[55]));
  2189.             if (uvalue == 0) // PP_PICA
  2190.             {   strcat(tempstring1, "0 (pica)");
  2191.             } elif (uvalue == 1) // PP_ELITE
  2192.             {   strcat(tempstring1, "1 (elite)");
  2193.             } elif (uvalue == 2) // PP_FINE
  2194.             {   strcat(tempstring1, "2 (fine)");
  2195.             } else
  2196.             {   strcat(tempstring1, "?");
  2197.             }
  2198.             AddNameToTail(&List2, tempstring1);
  2199.  
  2200.             strcpy(tempstring1, "Spacing:                ");
  2201.             uvalue = getuword(&(contents[which].DataPtr[57]));
  2202.             if (uvalue == 0) // PS_SIX_LPI
  2203.             {   strcat(tempstring1, "0 (6 lines per inch)");
  2204.             } elif (uvalue == 1) // PS_EIGHT_LPI
  2205.             {   strcat(tempstring1, "1 (8 lines per inch)");
  2206.             } else
  2207.             {   strcat(tempstring1, "?");
  2208.             }
  2209.             AddNameToTail(&List2, tempstring1);
  2210.  
  2211.             strcpy(tempstring1, "Left margin:            ");
  2212.             uvalue = getuword(&(contents[which].DataPtr[59]));
  2213.             stcl_d(tempstring2, uvalue);
  2214.             strcat(tempstring1, tempstring2);
  2215.             AddNameToTail(&List2, tempstring1);
  2216.  
  2217.             strcpy(tempstring1, "Right margin:           ");
  2218.             uvalue = getuword(&(contents[which].DataPtr[61]));
  2219.             stcl_d(tempstring2, uvalue);
  2220.             strcat(tempstring1, tempstring2);
  2221.             AddNameToTail(&List2, tempstring1);
  2222.  
  2223.             strcpy(tempstring1, "Quality:                ");
  2224.             uvalue = getuword(&(contents[which].DataPtr[63]));
  2225.             if (uvalue == 0) // PQ_DRAFT
  2226.             {   strcat(tempstring1, "0 (draft)");
  2227.             } elif (uvalue == 1) // PQ_LETTER
  2228.             {   strcat(tempstring1, "1 (letter)");
  2229.             } else
  2230.             {   strcat(tempstring1, "?");
  2231.             }
  2232.             AddNameToTail(&List2, tempstring1);
  2233.         }   }
  2234.         elif (!strcmp(contents[which].name, "SOND"))
  2235.         {   chunkdesc("Sound preferences", TRUE);
  2236.  
  2237.             // 16 reserved bytes at start
  2238.  
  2239.         if (!iff.raw)
  2240.         {
  2241.             strcpy(tempstring1, "Flash display?          ");
  2242.             uvalue = getuword(&contents[which].DataPtr[16]); // BOOL
  2243.             if (uvalue)
  2244.             {   strcat(tempstring1, "Yes");
  2245.             } else
  2246.             {   strcat(tempstring1, "No");
  2247.             }
  2248.             AddNameToTail(&List2, tempstring1);
  2249.  
  2250.             strcpy(tempstring1, "Make sounds?            ");
  2251.             uvalue = getuword(&contents[which].DataPtr[18]); // BOOL
  2252.             if (uvalue)
  2253.             {   strcat(tempstring1, "Yes");
  2254.             } else
  2255.             {   strcat(tempstring1, "No");
  2256.             }
  2257.             AddNameToTail(&List2, tempstring1);
  2258.  
  2259.             strcpy(tempstring1, "Type of sound:          ");
  2260.             uvalue = getuword(&contents[which].DataPtr[20]); // uword
  2261.             if (uvalue == 0) // SPTYPE_BEEP
  2262.             {   strcat(tempstring1, "Beep");
  2263.             } elif (uvalue == 1) // SPTYPE_SAMPLE
  2264.             {   strcat(tempstring1, "Sample");
  2265.             }
  2266.             AddNameToTail(&List2, tempstring1);
  2267.  
  2268.             strcpy(tempstring1, "Volume:                 ");
  2269.             uvalue = getuword(&contents[which].DataPtr[22]); // uword
  2270.             stcl_d(tempstring2, uvalue);
  2271.             strcat(tempstring1, tempstring2);
  2272.             if (uvalue > 64)
  2273.             {   strcat(tempstring1, "!");
  2274.             }
  2275.             strcat(tempstring1, "/64");
  2276.             AddNameToTail(&List2, tempstring1);
  2277.  
  2278.             strcpy(tempstring1, "Period:                 ");
  2279.             uvalue = getuword(&contents[which].DataPtr[24]); // uword
  2280.             stcl_d(tempstring2, uvalue);
  2281.             strcat(tempstring1, tempstring2);
  2282.             if (uvalue < 127 || uvalue > 2500)
  2283.             {   strcat(tempstring1, "!");
  2284.             }
  2285.             AddNameToTail(&List2, tempstring1);
  2286.  
  2287.             strcpy(tempstring1, "Beep length:            ");
  2288.             uvalue = getuword(&contents[which].DataPtr[26]); // uword
  2289.             stcl_d(tempstring2, uvalue);
  2290.             strcat(tempstring1, tempstring2);
  2291.             AddNameToTail(&List2, tempstring1);
  2292.  
  2293.             strcpy(tempstring1, "Sample filename:        ");
  2294.             strcat(tempstring1, &contents[which].DataPtr[28]); // 256 chars
  2295.             AddNameToTail(&List2, tempstring1);
  2296.         }   }
  2297.         elif (!strcmp(contents[which].name, "PTRN"))
  2298.         {   chunkdesc("Workbench pattern preferences", TRUE);
  2299.  
  2300.             // 16 reserved bytes at start
  2301.  
  2302.         if (!iff.raw)
  2303.         {
  2304.             strcpy(tempstring1, "Which pattern?          ");
  2305.             uvalue = getuword(&contents[which].DataPtr[16]); // UWORD
  2306.             if (uvalue == 0) // WBP_ROOT
  2307.             {   strcat(tempstring1, "9 (Workbench)");
  2308.             } elif (uvalue == 1) // WBP_DRAWER
  2309.             {   strcat(tempstring1, "1 (window)");
  2310.             } elif (uvalue == 2) // WBP_SCREEN
  2311.             {   strcat(tempstring1, "2 (screen)");
  2312.             } else
  2313.             {   strcat(tempstring1, "?");
  2314.             }
  2315.             AddNameToTail(&List2, tempstring1);
  2316.  
  2317.             uvalue = getuword(&contents[which].DataPtr[18]); // UWORD
  2318.  
  2319.             strcpy(tempstring1, "Data contains pattern?  ");
  2320.             if (uvalue & 1) // WBPF_PATTERN
  2321.             {   strcat(tempstring1, "Yes");
  2322.             } else
  2323.             {   strcat(tempstring1, "No");
  2324.             }
  2325.             AddNameToTail(&List2, tempstring1);
  2326.  
  2327.             strcpy(tempstring1, "Remap pattern?          ");
  2328.             if (uvalue & 16) // WBPF_NOREMAP
  2329.             {   strcat(tempstring1, "No");
  2330.             } else
  2331.             {   strcat(tempstring1, "Yes");
  2332.             }
  2333.             AddNameToTail(&List2, tempstring1);
  2334.  
  2335.             strcpy(tempstring1, "Dither quality:         ");
  2336.             if (uvalue & 768) // these comparisons are order-dependent
  2337.             {   strcat(tempstring1, "Best");
  2338.             } elif (uvalue & 512)
  2339.             {   strcat(tempstring1, "Good");
  2340.             } elif (uvalue & 256)
  2341.             {   strcat(tempstring1, "Poor");
  2342.             } else
  2343.             {   strcat(tempstring1, "Default");
  2344.             }
  2345.             AddNameToTail(&List2, tempstring1);
  2346.  
  2347.             strcpy(tempstring1, "Colour quality:         ");
  2348.             if (uvalue & 3072) // these comparisons are order-dependent
  2349.             {   strcat(tempstring1, "Best");
  2350.             } elif (uvalue & 2048)
  2351.             {   strcat(tempstring1, "Good");
  2352.             } elif (uvalue & 1024)
  2353.             {   strcat(tempstring1, "Poor");
  2354.             } else
  2355.             {   strcat(tempstring1, "Default");
  2356.             }
  2357.             AddNameToTail(&List2, tempstring1);
  2358.  
  2359.             strcpy(tempstring1, "Layout:                 ");
  2360.             if (uvalue & 12288) // these comparisons are order-dependent
  2361.             {   strcat(tempstring1, "Scale well");
  2362.             } elif (uvalue & 8192)
  2363.             {   strcat(tempstring1, "Scale");
  2364.             } elif (uvalue & 4096)
  2365.             {   strcat(tempstring1, "Centre");
  2366.             } else
  2367.             {   strcat(tempstring1, "Tile");
  2368.             }
  2369.             AddNameToTail(&List2, tempstring1);
  2370.  
  2371.             strcpy(tempstring1, "Revision:               ");  // BYTE
  2372.             stcl_d(tempstring2, contents[which].DataPtr[20]);
  2373.             strcat(tempstring1, tempstring2);
  2374.             AddNameToTail(&List2, tempstring1);
  2375.  
  2376.             strcpy(tempstring1, "Pattern depth:          ");  // BYTE
  2377.             stcl_d(tempstring2, contents[which].DataPtr[21]);
  2378.             strcat(tempstring1, tempstring2);
  2379.             AddNameToTail(&List2, tempstring1);
  2380.  
  2381.             strcpy(tempstring1, "Data length:            ");  // UWORD
  2382.             uvalue = getuword(&contents[which].DataPtr[22]);
  2383.             stcl_d(tempstring2, uvalue);
  2384.             strcat(tempstring1, tempstring2);
  2385.             AddNameToTail(&List2, tempstring1);
  2386.         }   }
  2387.         elif (!strcmp(contents[which].name, "PNTR"))
  2388.         {   chunkdesc("Pointer preferences", TRUE);
  2389.  
  2390.             // 16 reserved bytes at start
  2391.  
  2392.         if (!iff.raw)
  2393.         {
  2394.             strcpy(tempstring1, "Which pointer?          ");
  2395.             uvalue = getuword(&contents[which].DataPtr[16]); // UWORD
  2396.             if (uvalue == 0)
  2397.             {   strcat(tempstring1, "Normal");
  2398.             } elif (uvalue == 1)
  2399.             {   strcat(tempstring1, "Busy");
  2400.             } else
  2401.             {   strcat(tempstring1, "?");
  2402.             }
  2403.             AddNameToTail(&List2, tempstring1);
  2404.  
  2405.             strcpy(tempstring1, "Horizontal size:        ");
  2406.             uvalue = getuword(&contents[which].DataPtr[18]); // UWORD
  2407.             if (uvalue == 0) // POINTERXRESN_DEFAULT
  2408.             {   strcat(tempstring1, "0 (default)");
  2409.             } elif (uvalue == 1) // POINTERXRESN_140NS
  2410.             {   strcat(tempstring1, "1 (140ns)");
  2411.             } elif (uvalue == 2) // POINTERXRESN_70NS
  2412.             {   strcat(tempstring1, "2 (70ns)");
  2413.             } elif (uvalue == 3) // POINTERXRESN_35NS
  2414.             {   strcat(tempstring1, "3 (35ns)");
  2415.             } elif (uvalue == 4) // POINTERXRESN_SCREENRES
  2416.             {   strcat(tempstring1, "4 (screen)");
  2417.             } elif (uvalue == 5) // POINTERXRESN_LORES
  2418.             {   strcat(tempstring1, "5 (low resolution)");
  2419.             } elif (uvalue == 6) // POINTERXRESN_HIRES
  2420.             {   strcat(tempstring1, "6 (high resolution)");
  2421.             } else
  2422.             {   strcat(tempstring1, "?");
  2423.             }
  2424.             AddNameToTail(&List2, tempstring1);
  2425.  
  2426.             stcl_d(tempstring2, uvalue);
  2427.             strcat(tempstring1, tempstring2);
  2428.             AddNameToTail(&List2, tempstring1);
  2429.  
  2430.             strcpy(tempstring1, "Width:                  ");
  2431.             uvalue = getuword(&contents[which].DataPtr[20]); // UWORD
  2432.             stcl_d(tempstring2, uvalue);
  2433.             strcat(tempstring1, tempstring2);
  2434.             strcat(tempstring1, " pixels");
  2435.             AddNameToTail(&List2, tempstring1);
  2436.  
  2437.             strcpy(tempstring1, "Height:                 ");
  2438.             uvalue = getuword(&contents[which].DataPtr[22]); // UWORD
  2439.             stcl_d(tempstring2, uvalue);
  2440.             strcat(tempstring1, tempstring2);
  2441.             strcat(tempstring1, " pixels");
  2442.             AddNameToTail(&List2, tempstring1);
  2443.  
  2444.             strcpy(tempstring1, "Depth:                  ");
  2445.             uvalue = getuword(&contents[which].DataPtr[24]); // UWORD
  2446.             stcl_d(tempstring2, uvalue);
  2447.             strcat(tempstring1, tempstring2);
  2448.             strcat(tempstring1, " planes");
  2449.             AddNameToTail(&List2, tempstring1);
  2450.  
  2451.             strcpy(tempstring1, "Vertical size:          ");
  2452.             uvalue = getuword(&contents[which].DataPtr[26]); // UWORD
  2453.             if (uvalue == 0) // POINTERYRESN_DEFAULT
  2454.             {   strcat(tempstring1, "0 (default)");
  2455.             } elif (uvalue == 1) // POINTERYRESN_HIGH
  2456.             {   strcat(tempstring1, "1 (high non-aspect)");
  2457.             } elif (uvalue == 2) // POINTERYRESN_HIGHASPECT
  2458.             {   strcat(tempstring1, "2 (high aspect)");
  2459.             } elif (uvalue == 3) // POINTERYRESN_SCREENRES
  2460.             {   strcat(tempstring1, "3 (screen non-aspect)");
  2461.             } elif (uvalue == 4) // POINTERYRESN_SCREENRESASPECT
  2462.             {   strcat(tempstring1, "4 (screen aspect)");
  2463.             } else
  2464.             {   strcat(tempstring1, "?");
  2465.             }
  2466.             AddNameToTail(&List2, tempstring1);
  2467.  
  2468.             strcpy(tempstring1, "Hotspot coordinates:    ");
  2469.             uvalue = getuword(&contents[which].DataPtr[28]); // UWORD
  2470.             stcl_d(tempstring2, uvalue);
  2471.             strcat(tempstring1, tempstring2);
  2472.             strcat(tempstring1, ",");
  2473.             uvalue = getuword(&contents[which].DataPtr[30]); // UWORD
  2474.             stcl_d(tempstring2, uvalue);
  2475.             strcat(tempstring1, tempstring2);
  2476.             AddNameToTail(&List2, tempstring1);
  2477.         }   }
  2478.         elif (!strcmp(contents[which].name, "PALT")) // ignored
  2479.         {   chunkdesc("Palette preferences", FALSE);
  2480.         } elif (!strcmp(contents[which].name, "AHIG"))
  2481.         {   chunkdesc("AHI global preferences", TRUE);
  2482.  
  2483.             if (!iff.raw)
  2484.             {   strcpy(tempstring1, "Debug level:            ");
  2485.                 uvalue = getuword(contents[which].DataPtr); // UWORD
  2486.                 stcl_d(tempstring2, uvalue);
  2487.                 strcat(tempstring1, tempstring2);
  2488.                 if (uvalue == 0)
  2489.                 {   strcat(tempstring1, " (none)");
  2490.                 } elif (uvalue == 1)
  2491.                 {   strcat(tempstring1, " (low)");
  2492.                 } elif (uvalue == 2)
  2493.                 {   strcat(tempstring1, " (high)");
  2494.                 } elif (uvalue == 3)
  2495.                 {   strcat(tempstring1, " (all)");
  2496.                 } else
  2497.                 {   strcat(tempstring1, " (?)");
  2498.                 }
  2499.                 AddNameToTail(&List2, tempstring1);
  2500.  
  2501.                 strcpy(tempstring1, "Disable surround sound? ");
  2502.                 uvalue = getuword(&contents[which].DataPtr[2]); // BOOL
  2503.                 if (uvalue)
  2504.                 {   strcat(tempstring1, "Yes");
  2505.                 } else
  2506.                 {   strcat(tempstring1, "No");
  2507.                 }
  2508.                 AddNameToTail(&List2, tempstring1);
  2509.  
  2510.                 strcpy(tempstring1, "Disable echo?           ");
  2511.                 uvalue = getuword(&contents[which].DataPtr[4]); // BOOL
  2512.                 if (uvalue)
  2513.                 {   strcat(tempstring1, "Yes");
  2514.                 } else
  2515.                 {   strcat(tempstring1, "No");
  2516.                 }
  2517.                 AddNameToTail(&List2, tempstring1);
  2518.  
  2519.                 strcpy(tempstring1, "Fast echo?              ");
  2520.                 uvalue = getuword(&contents[which].DataPtr[6]); // BOOL
  2521.                 if (uvalue)
  2522.                 {   strcat(tempstring1, "Yes");
  2523.                 } else
  2524.                 {   strcat(tempstring1, "No");
  2525.                 }
  2526.                 AddNameToTail(&List2, tempstring1);
  2527.  
  2528.                 strcpy(tempstring1, "Maximum CPU usage:      ");
  2529.                 svalue = getslong(&(contents[which].DataPtr[8]));
  2530.                 svalue /= 1024; // LONG (Fixed)
  2531.                 stcl_d(tempstring2, svalue);
  2532.                 strcat(tempstring1, tempstring2);
  2533.                 strcat(tempstring1, "/64");
  2534.                 AddNameToTail(&List2, tempstring1);
  2535.  
  2536.                 strcpy(tempstring1, "Clip master volume?     ");
  2537.                 uvalue = getuword(&contents[which].DataPtr[12]); // BOOL
  2538.                 if (uvalue)
  2539.                 {   strcat(tempstring1, "Yes");
  2540.                 } else
  2541.                 {   strcat(tempstring1, "No");
  2542.                 }
  2543.                 AddNameToTail(&List2, tempstring1);
  2544.         }   }
  2545.         elif (!strcmp(contents[which].name, "AHIU"))
  2546.         {   chunkdesc("AHI unit preferences", TRUE);
  2547.  
  2548.             if (!iff.raw)
  2549.             {   strcpy(tempstring1, "Unit:                   ");
  2550.                 stcl_d(tempstring2, contents[which].DataPtr[0]); // UBYTE
  2551.                 strcat(tempstring1, tempstring2);
  2552.                 AddNameToTail(&List2, tempstring1);
  2553.  
  2554.                 // byte 1 is a pad byte
  2555.  
  2556.                 strcpy(tempstring1, "Channels:               ");
  2557.                 uvalue = getuword(&contents[which].DataPtr[2]); // UWORD
  2558.                 stcl_d(tempstring2, uvalue);
  2559.                 strcat(tempstring1, tempstring2);
  2560.                 AddNameToTail(&List2, tempstring1);
  2561.  
  2562.                 strcpy(tempstring1, "Audio mode:             ");
  2563.                 uvalue = getuword(&contents[which].DataPtr[4]); // ULONG
  2564.                 stcl_d(tempstring2, uvalue);
  2565.                 strcat(tempstring1, tempstring2);
  2566.                 AddNameToTail(&List2, tempstring1); // perhaps this can be interpreted?
  2567.  
  2568.                 strcpy(tempstring1, "Frequency:              ");
  2569.                 uvalue = getuword(&contents[which].DataPtr[8]); // ULONG
  2570.                 stcl_d(tempstring2, uvalue);
  2571.                 strcat(tempstring1, tempstring2);
  2572.                 AddNameToTail(&List2, tempstring1);
  2573.  
  2574.                 strcpy(tempstring1, "Monitor volume:         ");
  2575.                 svalue = getslong(&(contents[which].DataPtr[12]));
  2576.                 svalue /= 1024; // LONG (Fixed)
  2577.                 stcl_d(tempstring2, svalue);
  2578.                 strcat(tempstring1, tempstring2);
  2579.                 strcat(tempstring1, "/64");
  2580.                 AddNameToTail(&List2, tempstring1);
  2581.  
  2582.                 strcpy(tempstring1, "Input gain:             ");
  2583.                 svalue = getslong(&(contents[which].DataPtr[16]));
  2584.                 svalue /= 1024; // LONG (Fixed)
  2585.                 stcl_d(tempstring2, svalue);
  2586.                 strcat(tempstring1, tempstring2);
  2587.                 strcat(tempstring1, "/64");
  2588.                 AddNameToTail(&List2, tempstring1);
  2589.  
  2590.                 strcpy(tempstring1, "Output volume:          ");
  2591.                 svalue = getslong(&(contents[which].DataPtr[20]));
  2592.                 svalue /= 1024; // LONG (Fixed)
  2593.                 stcl_d(tempstring2, svalue);
  2594.                 strcat(tempstring1, tempstring2);
  2595.                 strcat(tempstring1, "/64");
  2596.                 AddNameToTail(&List2, tempstring1);
  2597.  
  2598.                 strcpy(tempstring1, "Input:                  ");
  2599.                 uvalue = getuword(&contents[which].DataPtr[24]); // ULONG
  2600.                 stcl_d(tempstring2, uvalue);
  2601.                 strcat(tempstring1, tempstring2);
  2602.                 AddNameToTail(&List2, tempstring1); // perhaps this can be interpreted?
  2603.  
  2604.                 strcpy(tempstring1, "Output:                 ");
  2605.                 uvalue = getuword(&contents[which].DataPtr[28]); // ULONG
  2606.                 stcl_d(tempstring2, uvalue);
  2607.                 strcat(tempstring1, tempstring2);
  2608.                 AddNameToTail(&List2, tempstring1); // perhaps this can be interpreted?
  2609.         }   }
  2610.         elif (!strcmp(contents[which].name, "WBNC"))
  2611.         {   chunkdesc("Workbench preferences", TRUE);
  2612.  
  2613.         if (!iff.raw)
  2614.         {
  2615.             strcpy(tempstring1, "Default stack size:     ");
  2616.             uvalue = getulong(contents[which].DataPtr); // ULONG
  2617.             stcl_d(tempstring2, uvalue);
  2618.             strcat(tempstring1, tempstring2);
  2619.             strcat(tempstring1, " bytes");
  2620.             AddNameToTail(&List2, tempstring1);
  2621.  
  2622.             strcpy(tempstring1, "Type restart time:      ");
  2623.             uvalue = getulong(&contents[which].DataPtr[4]); // ULONG
  2624.             stcl_d(tempstring2, uvalue);
  2625.             strcat(tempstring1, tempstring2);
  2626.             strcat(tempstring1, " seconds");
  2627.             AddNameToTail(&List2, tempstring1);
  2628.  
  2629.             strcpy(tempstring1, "Icon precision:         ");
  2630.             uvalue = getulong(&contents[which].DataPtr[8]); // ULONG
  2631.             if (uvalue == (ULONG) -1) // PRECISION_EXACT
  2632.             {   strcat(tempstring1, "-1 (exact)");
  2633.             } elif (uvalue == 0) // PRECISION_IMAGE
  2634.             {   strcat(tempstring1, "0 (image)");
  2635.             } elif (uvalue == 16) // PRECISION_ICON
  2636.             {   strcat(tempstring1, "16 (icon)");
  2637.             } elif (uvalue == 32) // PRECISION_GUI
  2638.             {   strcat(tempstring1, "32 (GUI)");
  2639.             } else
  2640.             {   strcat(tempstring1, "?");
  2641.             }
  2642.             AddNameToTail(&List2, tempstring1);
  2643.  
  2644.             strcpy(tempstring1, "Emboss rectangle:       ");
  2645.  
  2646.             strcpy(tempstring1, " Top-left corner:       ");
  2647.             svalue = getsword(&contents[which].DataPtr[12]); // WORD
  2648.             stcl_d(tempstring2, svalue);
  2649.             strcat(tempstring1, tempstring2);
  2650.             strcat(tempstring1, ",");
  2651.             svalue = getuword(&contents[which].DataPtr[14]); // WORD
  2652.             stcl_d(tempstring2, svalue);
  2653.             strcat(tempstring1, tempstring2);
  2654.             AddNameToTail(&List2, tempstring1);
  2655.  
  2656.             strcpy(tempstring1, " Bottom-right corner:   ");
  2657.             svalue = getsword(&contents[which].DataPtr[16]); // WORD
  2658.             stcl_d(tempstring2, svalue);
  2659.             strcat(tempstring1, tempstring2);
  2660.             strcat(tempstring1, ",");
  2661.             svalue = getuword(&contents[which].DataPtr[18]); // WORD
  2662.             stcl_d(tempstring2, svalue);
  2663.             strcat(tempstring1, tempstring2);
  2664.             AddNameToTail(&List2, tempstring1);
  2665.  
  2666.             strcpy(tempstring1, "Borderless?             ");
  2667.             uvalue = getuword(&contents[which].DataPtr[20]); // BOOL
  2668.             if (uvalue)
  2669.             {   strcat(tempstring1, "Yes");
  2670.             } else
  2671.             {   strcat(tempstring1, "No");
  2672.             }
  2673.             AddNameToTail(&List2, tempstring1);
  2674.  
  2675.             strcpy(tempstring1, "Max. filename length:   ");
  2676.             svalue = getslong(&contents[which].DataPtr[22]); // LONG
  2677.             stcl_d(tempstring2, svalue);
  2678.             strcat(tempstring1, tempstring2);
  2679.             strcat(tempstring1, " characters");
  2680.             AddNameToTail(&List2, tempstring1);
  2681.  
  2682.             strcpy(tempstring1, "NewIcons support?       ");
  2683.             uvalue = getuword(&contents[which].DataPtr[26]); // BOOL
  2684.             if (uvalue)
  2685.             {   strcat(tempstring1, "Yes");
  2686.             } else
  2687.             {   strcat(tempstring1, "No");
  2688.             }
  2689.             AddNameToTail(&List2, tempstring1);
  2690.  
  2691.             strcpy(tempstring1, "ColourIcons support?    ");
  2692.             uvalue = getuword(&contents[which].DataPtr[28]); // BOOL
  2693.             if (uvalue)
  2694.             {   strcat(tempstring1, "Yes");
  2695.             } else
  2696.             {   strcat(tempstring1, "No");
  2697.             }
  2698.             AddNameToTail(&List2, tempstring1);
  2699.  
  2700.             // remainder of these are new for OS3.9
  2701.  
  2702.             if (contents[which].bytes > 30)
  2703.             {   strcpy(tempstring1, "Image memory type:      ");
  2704.                 uvalue = getulong(&contents[which].DataPtr[30]); // ULONG
  2705.                 if (uvalue == 1)
  2706.                 {   strcat(tempstring1, "Other memory");
  2707.                 } elif (uvalue == 2)
  2708.                 {   strcat(tempstring1, "Graphics (chip) memory");
  2709.                 } else
  2710.                 {   strcat(tempstring1, "?");
  2711.                 }
  2712.                 AddNameToTail(&List2, tempstring1);
  2713.  
  2714.                 strcpy(tempstring1, "Lock pens?              ");
  2715.                 uvalue = getuword(&contents[which].DataPtr[34]); // BOOL
  2716.                 if (uvalue)
  2717.                 {   strcat(tempstring1, "Yes");
  2718.                 } else
  2719.                 {   strcat(tempstring1, "No");
  2720.                 }
  2721.                 AddNameToTail(&List2, tempstring1);
  2722.  
  2723.                 strcpy(tempstring1, "Title bar?              "); // this is inverted
  2724.                 uvalue = getuword(&contents[which].DataPtr[36]); // BOOL
  2725.                 if (uvalue)
  2726.                 {   strcat(tempstring1, "No");
  2727.                 } else
  2728.                 {   strcat(tempstring1, "Yes");
  2729.                 }
  2730.                 AddNameToTail(&List2, tempstring1);
  2731.  
  2732.                 strcpy(tempstring1, "Volume gauge?           "); // this is inverted
  2733.                 uvalue = getuword(&contents[which].DataPtr[38]); // BOOL
  2734.                 if (uvalue)
  2735.                 {   strcat(tempstring1, "No");
  2736.                 } else
  2737.                 {   strcat(tempstring1, "Yes");
  2738.                 }
  2739.                 AddNameToTail(&List2, tempstring1);
  2740.         }   }   }
  2741.         elif (!strcmp(contents[which].name, "WBHD"))
  2742.         {   chunkdesc("Workbench hidden device preferences", TRUE);
  2743.  
  2744.             if (!iff.raw)
  2745.             {   strcpy(tempstring1, "Name:                   ");
  2746.                 strcat(tempstring1, contents[which].DataPtr);
  2747.                 AddNameToTail(&List2, tempstring1);
  2748.         }   }
  2749.         elif (!strcmp(contents[which].name, "LCLE"))
  2750.         {   chunkdesc("Locale preferences", TRUE);
  2751.  
  2752.             // 16 reserved bytes at start
  2753.  
  2754.         if (!iff.raw)
  2755.         {
  2756.             strcpy(tempstring1, "Country code:           ");
  2757.             strcpy(tempstring1, &contents[which].DataPtr[16]); // 16 chars
  2758.             AddNameToTail(&List2, tempstring1);
  2759.  
  2760.             strcpy(tempstring1, "Preferred languages:    ");
  2761.             strcpy(tempstring1, &contents[which].DataPtr[16]); // 16 chars
  2762.             AddNameToTail(&List2, tempstring1);
  2763.  
  2764.             for (i = 1; i <= 10; i++)
  2765.             {   strcpy(tempstring1, " ");
  2766.                 if (i < 10)
  2767.                 {   strcat(tempstring1, " ");
  2768.                 }
  2769.                 stcl_d(tempstring2, i);
  2770.                 strcat(tempstring1, tempstring2);
  2771.                 strcpy(tempstring1, ":                    ");
  2772.                 strcat(tempstring1, &contents[which].DataPtr[48 + ((i - 1) * 30)]); // 10 entries of 30 chars each
  2773.                 AddNameToTail(&List2, tempstring1);
  2774.             }
  2775.  
  2776.             strcpy(tempstring1, "Time from GMT:          ");
  2777.             svalue = getslong(&contents[which].DataPtr[348]); // LONG
  2778.             stcl_d(tempstring2, svalue);
  2779.             strcat(tempstring1, tempstring2);
  2780.             strcat(tempstring1, " minutes");
  2781.             AddNameToTail(&List2, tempstring1);
  2782.  
  2783.             strcpy(tempstring1, "Flags:                  ");
  2784.             uvalue = getulong(&contents[which].DataPtr[352]); // ULONG
  2785.             stcl_d(tempstring2, uvalue);
  2786.             strcat(tempstring1, tempstring2);
  2787.             AddNameToTail(&List2, tempstring1);
  2788.  
  2789.             docountry(&contents[which].DataPtr[356]);
  2790.         }   }
  2791.         elif (!strcmp(contents[which].name, "CTRY"))
  2792.         {   chunkdesc("Country preferences", TRUE);
  2793.  
  2794.             if (!iff.raw)
  2795.             {   docountry(contents[which].DataPtr);
  2796.         }   }
  2797.         elif (!strcmp(contents[which].name, "RACT"))
  2798.         {   chunkdesc("ReAction preferences", TRUE);
  2799.  
  2800.         if (!iff.raw)
  2801.         {
  2802.             strcpy(tempstring1, "Bevel type:             "); // UWORD
  2803.             uvalue = getuword(contents[which].DataPtr);
  2804.             if (uvalue == 0) // BVT_GT
  2805.             {   strcat(tempstring1, "0 (GadTools 2:1)");
  2806.             } elif (uvalue == 1) // BVT_THIN
  2807.             {   strcat(tempstring1, "1 (ReAction 1:1)");
  2808.             } elif (uvalue == 2) // BVT_THICK
  2809.             {   strcat(tempstring1, "2 (ReAction 2:1)");
  2810.             } elif (uvalue == 3) // BVT_THIN
  2811.             {   strcat(tempstring1, "3 (XEN 2:1)");
  2812.             } elif (uvalue == 4) // BVT_THIN
  2813.             {   strcat(tempstring1, "4 (XEN 1:1)");
  2814.             } else
  2815.             {   strcat(tempstring1, "?");
  2816.             }
  2817.             AddNameToTail(&List2, tempstring1);
  2818.  
  2819.             strcpy(tempstring1, "Glyph type:             "); // UWORD
  2820.             uvalue = getuword(&contents[which].DataPtr[2]);
  2821.             if (uvalue == 0) // GLT_GT
  2822.             {   strcat(tempstring1, "0 (GadTools)");
  2823.             } elif (uvalue == 1) // GLT_FLAT
  2824.             {   strcat(tempstring1, "1 (Flat)");
  2825.             } elif (uvalue == 2) // GLT_3D
  2826.             {   strcat(tempstring1, "2 (3D)");
  2827.             } else
  2828.             {   strcat(tempstring1, "?");
  2829.             }
  2830.             AddNameToTail(&List2, tempstring1);
  2831.  
  2832.             strcpy(tempstring1, "Layout spacing:         "); // UWORD
  2833.             uvalue = getuword(&contents[which].DataPtr[4]);
  2834.             stcl_d(tempstring2, uvalue);
  2835.             strcat(tempstring1, tempstring2);
  2836.             AddNameToTail(&List2, tempstring1);
  2837.  
  2838.             strcpy(tempstring1, "3D Proportional?        ");
  2839.             uvalue = getuword(&contents[which].DataPtr[6]); // BOOL
  2840.             if (uvalue)
  2841.             {   strcat(tempstring1, "Yes");
  2842.             } else
  2843.             {   strcat(tempstring1, "No");
  2844.             }
  2845.             AddNameToTail(&List2, tempstring1);
  2846.  
  2847.             strcpy(tempstring1, "Label pen:              "); // UWORD
  2848.             uvalue = getuword(&contents[which].DataPtr[8]);
  2849.             stcl_d(tempstring2, uvalue);
  2850.             strcat(tempstring1, tempstring2);
  2851.             AddNameToTail(&List2, tempstring1);
  2852.  
  2853.             strcpy(tempstring1, "Label placement:        "); // UWORD
  2854.             uvalue = getuword(&contents[which].DataPtr[10]);
  2855.             /* This has been reverse-engineered
  2856.             using the ReAction preferences editor */
  2857.             if (uvalue == 0)
  2858.             {   strcat(tempstring1, "0 (centre)");
  2859.             } elif (uvalue == 1)
  2860.             {   strcat(tempstring1, "1 (left)");
  2861.             } elif (uvalue == 2)
  2862.             {   strcat(tempstring1, "2 (right)");
  2863.             }
  2864.             AddNameToTail(&List2, tempstring1);
  2865.  
  2866.             strcpy(tempstring1, "3D Label?               ");
  2867.             uvalue = getuword(&contents[which].DataPtr[12]); // BOOL
  2868.             if (uvalue)
  2869.             {   strcat(tempstring1, "Yes");
  2870.             } else
  2871.             {   strcat(tempstring1, "No");
  2872.             }
  2873.             AddNameToTail(&List2, tempstring1);
  2874.  
  2875.             strcpy(tempstring1, "Refreshing Method:      ");
  2876.             uvalue = getuword(&contents[which].DataPtr[14]); // BOOL
  2877.             if (uvalue)
  2878.             {   strcat(tempstring1, "Simple");
  2879.             } else
  2880.             {   strcat(tempstring1, "Smart");
  2881.             }
  2882.             AddNameToTail(&List2, tempstring1);
  2883.  
  2884.             strcpy(tempstring1, "3D Look?                ");
  2885.             uvalue = getuword(&contents[which].DataPtr[16]); // BOOL
  2886.             if (uvalue)
  2887.             {   strcat(tempstring1, "Yes");
  2888.             } else
  2889.             {   strcat(tempstring1, "No");
  2890.             }
  2891.             AddNameToTail(&List2, tempstring1);
  2892.  
  2893.             AddNameToTail(&List2, "Fallback font:");
  2894.             dotextattr(&contents[which].DataPtr[18]); // struct TextAttr (8 bytes)
  2895.             AddNameToTail(&List2, "Label font:");
  2896.             dotextattr(&contents[which].DataPtr[26]); // struct TextAttr (8 bytes)
  2897.  
  2898.             strcpy(tempstring1, "Fallback font name:     ");
  2899.             strcat(tempstring1, &contents[which].DataPtr[34]); // 128 UBYTEs
  2900.             AddNameToTail(&List2, tempstring1);
  2901.  
  2902.             strcpy(tempstring1, "Label font name:        ");
  2903.             strcat(tempstring1, &contents[which].DataPtr[162]); // 128 UBYTEs
  2904.             AddNameToTail(&List2, tempstring1);
  2905.  
  2906.             strcpy(tempstring1, "Backdrop pattern:       ");
  2907.             strcat(tempstring1, &contents[which].DataPtr[290]); // 256 UBYTEs
  2908.             AddNameToTail(&List2, tempstring1);
  2909.         }   }
  2910.         elif (!strcmp(contents[which].name, "PRHD"))
  2911.         {   chunkdesc("Preferences header", TRUE);
  2912.  
  2913.         if (!iff.raw)
  2914.         {
  2915.             strcpy(tempstring1, "Version:                ");
  2916.             stcl_d(tempstring2, contents[which].DataPtr[0]);
  2917.             strcat(tempstring1, tempstring2);
  2918.             AddNameToTail(&List2, tempstring1);
  2919.                                
  2920.             strcpy(tempstring1, "Type:                   ");
  2921.             stcl_d(tempstring2, contents[which].DataPtr[1]);
  2922.             strcat(tempstring1, tempstring2);
  2923.             AddNameToTail(&List2, tempstring1);
  2924.  
  2925.             strcpy(tempstring1, "Flags:                  ");
  2926.             uvalue = getuword(&(contents[which].DataPtr[2]));
  2927.             stcl_d(tempstring2, uvalue);
  2928.             strcat(tempstring1, tempstring2);
  2929.             AddNameToTail(&List2, tempstring1);
  2930.     }   }   }
  2931.     elif (!strcmp(queryform, "SMUS"))
  2932.     {   if (!strcmp(contents[which].name, "SHDR"))
  2933.         {   chunkdesc("Global information for the score", TRUE);
  2934.  
  2935.         if (!iff.raw)
  2936.         {
  2937.             strcpy(tempstring1, "Tempo:              ");
  2938.             uvalue = getuword(contents[which].DataPtr);
  2939.             uvalue = uvalue / 128;
  2940.             stcl_d(tempstring2, uvalue);
  2941.             strcat(tempstring1, tempstring2);
  2942.             strcat(tempstring1, " bpm");
  2943.             AddNameToTail(&List2, tempstring1);
  2944.  
  2945.             strcpy(tempstring1, "Volume:             ");
  2946.             uvalue = contents[which].DataPtr[2];
  2947.             stcl_d(tempstring2, uvalue);
  2948.             strcat(tempstring1, tempstring2);
  2949.             strcat(tempstring1, "/127");
  2950.             AddNameToTail(&List2, tempstring1);
  2951.  
  2952.             strcpy(tempstring1, "Tracks:             ");
  2953.             uvalue = contents[which].DataPtr[3];
  2954.             stcl_d(tempstring2, uvalue);
  2955.             strcat(tempstring1, tempstring2);
  2956.             AddNameToTail(&List2, tempstring1);
  2957.         }   }
  2958.         elif (!strcmp(contents[which].name, "INS1"))
  2959.         {   chunkdesc("Identifies an instrument to use", TRUE);
  2960.  
  2961.         if (!iff.raw)
  2962.         {
  2963.             strcpy(tempstring1, "Register number:    ");
  2964.             stcl_d(tempstring2, contents[which].DataPtr[0]); // UBYTE
  2965.             strcat(tempstring1, tempstring2);
  2966.             AddNameToTail(&List2, tempstring1);
  2967.  
  2968.             strcpy(tempstring1, "Reference type:     ");
  2969.             if (contents[which].DataPtr[1] == 0) // UBYTE
  2970.             {   strcat(tempstring1, "Find by name");
  2971.             } elif (contents[which].DataPtr[1] == 1)
  2972.             {   strcat(tempstring1, "Find on MIDI");
  2973.             } else strcat(tempstring1, "?");
  2974.             AddNameToTail(&List2, tempstring1);
  2975.  
  2976.             strcpy(tempstring1, "MIDI channel:       ");
  2977.             if (contents[which].DataPtr[1] == 1) // if find on MIDI
  2978.             {   stcl_d(tempstring2, contents[which].DataPtr[2]); // UBYTE
  2979.                 strcat(tempstring1, tempstring2);
  2980.             } else strcat(tempstring1, "n/a");
  2981.             AddNameToTail(&List2, tempstring1);
  2982.  
  2983.             strcpy(tempstring1, "MIDI preset:        ");
  2984.             if (contents[which].DataPtr[1] == 1) // if find on MIDI
  2985.             {   stcl_d(tempstring2, contents[which].DataPtr[3]); // UBYTE
  2986.                 strcat(tempstring1, tempstring2);
  2987.             } else strcat(tempstring1, "n/a");
  2988.             AddNameToTail(&List2, tempstring1);
  2989.  
  2990.             strcpy(tempstring1, "Instrument name:    ");
  2991.             strcat(tempstring1, (STRPTR) contents[which].DataPtr + 4); // STRPTR
  2992.             AddNameToTail(&List2, tempstring1);
  2993.         }   }
  2994.         elif (!strcmp(contents[which].name, "TRAK"))
  2995.         {   chunkdesc("Linear stream of events", FALSE);
  2996.         } elif (!strcmp(contents[which].name, "INST"))
  2997.         {   chunkdesc("Obsolete; use INS1 instead", FALSE);
  2998.         } elif (!stricmp(contents[which].name, "IRev")) // this could also perhaps be IREV
  2999.         {   chunkdesc("Instant Music private chunk", FALSE);
  3000.         } elif (!strcmp(contents[which].name, "BIAS"))
  3001.         {   chunkdesc("Instant Music private chunk", FALSE);
  3002.     }   }
  3003.     elif (!strcmp(queryform, "HEAD"))
  3004.     {   if (!strcmp(contents[which].name, "NEST"))
  3005.         {   chunkdesc("Nesting level", TRUE);
  3006.  
  3007.             if (!iff.raw)
  3008.             {   strcpy(tempstring1, "Nesting level:      ");
  3009.                 uvalue = getuword(contents[which].DataPtr);
  3010.                 stcl_d(tempstring2, uvalue);
  3011.                 strcat(tempstring1, tempstring2);
  3012.                 AddNameToTail(&List2, tempstring1);
  3013.         }   }
  3014.         elif (!strcmp(contents[which].name, "TEXT"))
  3015.         {   chunkdesc("Heading text", FALSE);
  3016.     }   }
  3017.     elif (!strcmp(queryform, "WORD"))
  3018.     {   if (!strcmp(contents[which].name, "FONT"))
  3019.         {   chunkdesc("Font name/number table", TRUE);
  3020.  
  3021.         if (!iff.raw)
  3022.         {
  3023.             strcpy(tempstring1, "Number:             ");
  3024.             uvalue = contents[which].DataPtr[0]; // UBYTE
  3025.             stcl_d(tempstring2, uvalue);
  3026.             strcat(tempstring1, tempstring2);
  3027.             AddNameToTail(&List2, tempstring1);
  3028.  
  3029.             strcpy(tempstring1, "Size:               ");
  3030.             uvalue = getuword(&contents[which].DataPtr[1]);
  3031.             stcl_d(tempstring2, uvalue);
  3032.             strcat(tempstring1, tempstring2);
  3033.             AddNameToTail(&List2, tempstring1);
  3034.  
  3035.             strcpy(tempstring1, "Name:               ");
  3036.             strcat(tempstring1, &contents[which].DataPtr[3]);
  3037.             AddNameToTail(&List2, tempstring1);
  3038.         }   }
  3039.         elif (!strcmp(contents[which].name, "COLR"))
  3040.         {   chunkdesc("Colour translation table", TRUE);
  3041.  
  3042.             if (!iff.raw)
  3043.             {   for (i = 0; i <= 7; i++)
  3044.                 {   strcpy(tempstring1, "Colour ");
  3045.                     stcl_d(tempstring2, i);
  3046.                     strcat(tempstring1, tempstring2);
  3047.                     strcat(tempstring1, ":           ");
  3048.                     uvalue = contents[which].DataPtr[i]; // UBYTE
  3049.                     stcl_d(tempstring2, uvalue);
  3050.                     strcat(tempstring1, tempstring2);
  3051.                     AddNameToTail(&List2, tempstring1);
  3052.         }   }   }
  3053.         elif (!strcmp(contents[which].name, "DOC "))
  3054.         {   chunkdesc("Begin document section", TRUE);
  3055.  
  3056.             if (!iff.raw)
  3057.             {   strcpy(tempstring1, "Starting page:      ");
  3058.                 uvalue = getuword(contents[which].DataPtr);
  3059.                 stcl_d(tempstring2, uvalue);
  3060.                 strcat(tempstring1, tempstring2);
  3061.                 AddNameToTail(&List2, tempstring1);
  3062.  
  3063.                 strcpy(tempstring1, "Numbering style:    ");
  3064.                 if (contents[which].DataPtr[2] == 0)
  3065.                 {   strcat(tempstring1, "1, 2, 3...");
  3066.                 } elif (contents[which].DataPtr[2] == 1)
  3067.                 {   strcat(tempstring1, "I, II, III...");
  3068.                 } elif (contents[which].DataPtr[2] == 2)
  3069.                 {   strcat(tempstring1, "i, ii, iii...");
  3070.                 } elif (contents[which].DataPtr[2] == 3)
  3071.                 {   strcat(tempstring1, "A, B, C...");
  3072.                 } elif (contents[which].DataPtr[2] == 4)
  3073.                 {   strcat(tempstring1, "a, b, c...");
  3074.                 } else
  3075.                 {   strcat(tempstring1, "?");
  3076.                 }
  3077.                 AddNameToTail(&List2, tempstring1);
  3078.         }   }
  3079.         elif (!strcmp(contents[which].name, "HEAD"))
  3080.         {   chunkdesc("Begin header section", TRUE);
  3081.  
  3082.             if (!iff.raw)
  3083.             {   strcpy(tempstring1, "Page type:           ");
  3084.                 if (contents[which].DataPtr[0] == 0)
  3085.                 {   strcat(tempstring1, "None");
  3086.                 } elif (contents[which].DataPtr[0] == 1)
  3087.                 {   strcat(tempstring1, "Left");
  3088.                 } elif (contents[which].DataPtr[0] == 2)
  3089.                 {   strcat(tempstring1, "Right");
  3090.                 } elif (contents[which].DataPtr[0] == 3)
  3091.                 {   strcat(tempstring1, "Both");
  3092.                 } else strcat(tempstring1, "?");
  3093.                 AddNameToTail(&List2, tempstring1);
  3094.  
  3095.                 strcpy(tempstring1, "First page?          ");
  3096.                 if (contents[which].DataPtr[1] == 0)
  3097.                 {   strcat(tempstring1, "No");
  3098.                 } else strcat(tempstring1, "Yes");
  3099.                 AddNameToTail(&List2, tempstring1);
  3100.         }   }
  3101.         elif (!strcmp(contents[which].name, "FOOT"))
  3102.         {   chunkdesc("Begin footer section", TRUE);
  3103.  
  3104.             if (!iff.raw)
  3105.             {   strcpy(tempstring1, "Page type:           ");
  3106.                 if (contents[which].DataPtr[0] == 0)
  3107.                 {   strcat(tempstring1, "None");
  3108.                 } elif (contents[which].DataPtr[0] == 1)
  3109.                 {   strcat(tempstring1, "Left");
  3110.                 } elif (contents[which].DataPtr[0] == 2)
  3111.                 {   strcat(tempstring1, "Right");
  3112.                 } elif (contents[which].DataPtr[0] == 3)
  3113.                 {   strcat(tempstring1, "Both");
  3114.                 } else strcat(tempstring1, "?");
  3115.                 AddNameToTail(&List2, tempstring1);
  3116.  
  3117.                 strcpy(tempstring1, "First page?          ");
  3118.                 if (contents[which].DataPtr[1] == 0)
  3119.                 {   strcat(tempstring1, "No");
  3120.                 } else strcat(tempstring1, "Yes");
  3121.                 AddNameToTail(&List2, tempstring1);
  3122.         }   }
  3123.         elif (!strcmp(contents[which].name, "PCTS"))
  3124.         {   chunkdesc("Begin picture section", TRUE);
  3125.  
  3126.             if (!iff.raw)
  3127.             {   strcpy(tempstring1, "Bitplanes:           ");
  3128.                 uvalue = contents[which].DataPtr[0]; // UBYTE
  3129.                 stcl_d(tempstring2, uvalue);
  3130.                 strcat(tempstring1, tempstring2);
  3131.                 AddNameToTail(&List2, tempstring1);
  3132.         }   }
  3133.         elif (!strcmp(contents[which].name, "PARA"))
  3134.         {   chunkdesc("New paragraph format", TRUE);
  3135.  
  3136.         if (!iff.raw)
  3137.         {
  3138.             strcpy(tempstring1, "Left indent:         ");
  3139.             uvalue = getuword(contents[which].DataPtr); // UWORD
  3140.             stcl_d(tempstring2, uvalue);
  3141.             strcat(tempstring1, tempstring2);
  3142.             strcat(tempstring1, " decipoints");
  3143.             AddNameToTail(&List2, tempstring1);
  3144.  
  3145.             strcpy(tempstring1, "Left margin:         ");
  3146.             uvalue = getuword(&(contents[which].DataPtr[2])); // UWORD
  3147.             stcl_d(tempstring2, uvalue);
  3148.             strcat(tempstring1, tempstring2);
  3149.             strcat(tempstring1, " decipoints");
  3150.             AddNameToTail(&List2, tempstring1);
  3151.  
  3152.             strcpy(tempstring1, "Right margin:        ");
  3153.             uvalue = getuword(&(contents[which].DataPtr[4])); // UWORD
  3154.             stcl_d(tempstring2, uvalue);
  3155.             strcat(tempstring1, tempstring2);
  3156.             strcat(tempstring1, " decipoints");
  3157.             AddNameToTail(&List2, tempstring1);
  3158.  
  3159.             strcpy(tempstring1, "Line spacing:        ");
  3160.             if (contents[which].DataPtr[6] == 0)
  3161.             {   strcat(tempstring1, "Single");
  3162.             } elif (contents[which].DataPtr[6] == 16)
  3163.             {   strcat(tempstring1, "Double");
  3164.             } else
  3165.             {   strcat(tempstring1, "?");
  3166.             }
  3167.             AddNameToTail(&List2, tempstring1);
  3168.  
  3169.             strcpy(tempstring1, "Justification:       ");
  3170.             if (contents[which].DataPtr[7] == 0)
  3171.             {   strcat(tempstring1, "Left");
  3172.             } elif (contents[which].DataPtr[7] == 1)
  3173.             {   strcat(tempstring1, "Centre");
  3174.             } elif (contents[which].DataPtr[7] == 2)
  3175.             {   strcat(tempstring1, "Right");
  3176.             } elif (contents[which].DataPtr[7] == 3)
  3177.             {   strcat(tempstring1, "Full");
  3178.             } else
  3179.             {   strcat(tempstring1, "?");
  3180.             }
  3181.             AddNameToTail(&List2, tempstring1);
  3182.  
  3183.             strcpy(tempstring1, "Font number:         ");
  3184.             uvalue = contents[which].DataPtr[8]; // UBYTE
  3185.             stcl_d(tempstring2, uvalue);
  3186.             strcat(tempstring1, tempstring2);
  3187.             AddNameToTail(&List2, tempstring1);
  3188.  
  3189.             strcat(tempstring1, " Style:");
  3190.             AddNameToTail(&List2, tempstring1);
  3191.  
  3192.             strcat(tempstring1, " Underlined?         ");
  3193.             if (contents[which].DataPtr[9] & 1)
  3194.             {   strcat(tempstring1, "Yes");
  3195.             } else strcat(tempstring1, "No");
  3196.             AddNameToTail(&List2, tempstring1);
  3197.  
  3198.             strcat(tempstring1, " Bold?               ");
  3199.             if (contents[which].DataPtr[9] & 2)
  3200.             {   strcat(tempstring1, "Yes");
  3201.             } else strcat(tempstring1, "No");
  3202.             AddNameToTail(&List2, tempstring1);
  3203.  
  3204.             strcat(tempstring1, " Italic?             ");
  3205.             if (contents[which].DataPtr[9] & 4)
  3206.             {   strcat(tempstring1, "Yes");
  3207.             } else strcat(tempstring1, "No");
  3208.             AddNameToTail(&List2, tempstring1);
  3209.  
  3210.             strcat(tempstring1, " Extended?           ");
  3211.             if (contents[which].DataPtr[9] & 8)
  3212.             {   strcat(tempstring1, "Yes");
  3213.             } else strcat(tempstring1, "No");
  3214.             AddNameToTail(&List2, tempstring1);
  3215.  
  3216.             strcat(tempstring1, " ColourFont?         ");
  3217.             if (contents[which].DataPtr[9] & 64)
  3218.             {   strcat(tempstring1, "Yes");
  3219.             } else strcat(tempstring1, "No");
  3220.             AddNameToTail(&List2, tempstring1);
  3221.  
  3222.             strcat(tempstring1, " Tagged?             ");
  3223.             if (contents[which].DataPtr[9] & 128)
  3224.             {   strcat(tempstring1, "Yes");
  3225.             } else strcat(tempstring1, "No");
  3226.             AddNameToTail(&List2, tempstring1);
  3227.  
  3228.             strcpy(tempstring1, "Miscellaneous style: ");
  3229.             if (contents[which].DataPtr[10] == 0)
  3230.             {   strcat(tempstring1, "None");
  3231.             } elif (contents[which].DataPtr[10] == 1)
  3232.             {   strcat(tempstring1, "Superscript");
  3233.             } elif (contents[which].DataPtr[10] == 2)
  3234.             {   strcat(tempstring1, "Subscript");
  3235.             } else
  3236.             {   strcat(tempstring1, "?");
  3237.             }
  3238.             AddNameToTail(&List2, tempstring1);
  3239.  
  3240.             strcpy(tempstring1, "Colour:              ");
  3241.             uvalue = contents[which].DataPtr[11]; // UBYTE
  3242.             stcl_d(tempstring2, uvalue);
  3243.             strcat(tempstring1, tempstring2);
  3244.             AddNameToTail(&List2, tempstring1);
  3245.         }   }
  3246.         elif (!strcmp(contents[which].name, "TABS"))
  3247.         {   chunkdesc("New tab stop types/locations", TRUE);
  3248.  
  3249.         if (!iff.raw)
  3250.         {
  3251.             strcpy(tempstring1, "Position:            ");
  3252.             uvalue = getuword(contents[which].DataPtr); // UWORD
  3253.             stcl_d(tempstring2, uvalue);
  3254.             strcat(tempstring1, tempstring2);
  3255.             strcat(tempstring1, " decipoints");
  3256.             AddNameToTail(&List2, tempstring1);
  3257.  
  3258.             strcpy(tempstring1, "Type:                ");
  3259.             if (contents[which].DataPtr[2] == 0)
  3260.             {   strcat(tempstring1, "Left");
  3261.             } elif (contents[which].DataPtr[2] == 1)
  3262.             {   strcat(tempstring1, "Centre");
  3263.             } elif (contents[which].DataPtr[2] == 2)
  3264.             {   strcat(tempstring1, "Right");
  3265.             } elif (contents[which].DataPtr[2] == 3)
  3266.             {   strcat(tempstring1, "Decimal");
  3267.             } else
  3268.             {   strcat(tempstring1, "?");
  3269.             }
  3270.             AddNameToTail(&List2, tempstring1);
  3271.         }   }
  3272.         elif (!strcmp(contents[which].name, "PAGE"))
  3273.         {   chunkdesc("Page break", FALSE);
  3274.         } elif (!strcmp(contents[which].name, "TEXT"))
  3275.         {   chunkdesc("Paragraph text", FALSE);
  3276.         } elif (!strcmp(contents[which].name, "PINF"))
  3277.         {   chunkdesc("Picture info", TRUE);
  3278.  
  3279.         if (!iff.raw)
  3280.         {
  3281.             strcpy(tempstring1, "Width:               ");
  3282.             uvalue = getuword(contents[which].DataPtr); // UWORD
  3283.             stcl_d(tempstring2, uvalue);
  3284.             strcat(tempstring1, tempstring2);
  3285.             AddNameToTail(&List2, tempstring1);
  3286.  
  3287.             strcpy(tempstring1, "Height:              ");
  3288.             uvalue = getuword(&(contents[which].DataPtr[2])); // UWORD
  3289.             stcl_d(tempstring2, uvalue);
  3290.             strcat(tempstring1, tempstring2);
  3291.             AddNameToTail(&List2, tempstring1);
  3292.  
  3293.             strcpy(tempstring1, "Page:                ");
  3294.             uvalue = getuword(&(contents[which].DataPtr[4])); // UWORD
  3295.             stcl_d(tempstring2, uvalue);
  3296.             strcat(tempstring1, tempstring2);
  3297.             AddNameToTail(&List2, tempstring1);
  3298.  
  3299.             strcpy(tempstring1, "X-position:          ");
  3300.             uvalue = getuword(&(contents[which].DataPtr[6])); // UWORD
  3301.             stcl_d(tempstring2, uvalue);
  3302.             strcat(tempstring1, tempstring2);
  3303.             strcat(tempstring1, " decipoints");
  3304.             AddNameToTail(&List2, tempstring1);
  3305.  
  3306.             strcpy(tempstring1, "Y-position:          ");
  3307.             uvalue = getuword(&(contents[which].DataPtr[8])); // UWORD
  3308.             stcl_d(tempstring2, uvalue);
  3309.             strcat(tempstring1, tempstring2);
  3310.             strcat(tempstring1, " decipoints");
  3311.             AddNameToTail(&List2, tempstring1);
  3312.  
  3313.             strcpy(tempstring1, "Masking:            ");
  3314.             if (contents[which].DataPtr[10] == 0)
  3315.             {   strcat(tempstring1, "0 (Opaque)");
  3316.             } elif (contents[which].DataPtr[10] == 1)
  3317.             {   strcat(tempstring1, "1 (Mask plane)");
  3318.             } elif (contents[which].DataPtr[10] == 2)
  3319.             {   strcat(tempstring1, "2 (Transparent colour)");
  3320.             } elif (contents[which].DataPtr[10] == 3)
  3321.             {   strcat(tempstring1, "3 (Lasso)");
  3322.             } else strcat(tempstring1, "?");
  3323.             AddNameToTail(&List2, tempstring1);
  3324.  
  3325.             strcpy(tempstring1, "Compression:        ");
  3326.             if (contents[which].DataPtr[11] == 0)
  3327.             {   strcat(tempstring1, "None");
  3328.             } elif (contents[which].DataPtr[11] == 1)
  3329.             {   strcat(tempstring1, "Byte run encoding");
  3330.             } else strcat(tempstring1, "?");
  3331.             AddNameToTail(&List2, tempstring1);
  3332.  
  3333.             strcpy(tempstring1, "Transparent colour: ");
  3334.             if (contents[which].DataPtr[12] != 2
  3335.              && contents[which].DataPtr[12] != 3)
  3336.             {   strcat(tempstring1, "n/a");
  3337.             } else
  3338.             {   stcl_d(tempstring2, (256 * contents[which].DataPtr[12])
  3339.                                   +        contents[which].DataPtr[13]);
  3340.                 strcat(tempstring1, tempstring2);
  3341.             }
  3342.             AddNameToTail(&List2, tempstring1);
  3343.     }   }   }
  3344.     elif (!strcmp(queryform, "AIFF"))
  3345.     {   if (!strcmp(contents[which].name, "MIDI"))
  3346.         {   chunkdesc("Stores MIDI data", FALSE);
  3347.         } elif (!strcmp(contents[which].name, "MARK"))
  3348.         {   chunkdesc("Points to positions in the sound data", TRUE);
  3349.  
  3350.         if (!iff.raw)
  3351.         {
  3352.             strcpy(tempstring1, "Markers:             ");
  3353.             svalue = getsword(contents[which].DataPtr);
  3354.             stcl_d(tempstring2, svalue);
  3355.             strcat(tempstring1, tempstring2);
  3356.             if (svalue < 0)
  3357.             {   strcat(tempstring1, "!");
  3358.             }
  3359.             AddNameToTail(&List2, tempstring1);
  3360.             markers = svalue;
  3361.             if (markers > 0)
  3362.             {   currentpos = 2;
  3363.                 for (i = 1; i <= markers; i++)
  3364.                 {   strcpy(tempstring1, "Marker ");
  3365.                     stcl_d(tempstring2, i);
  3366.                     strcat(tempstring1, tempstring2);
  3367.                     strcat(tempstring1, ":");
  3368.                     AddNameToTail(&List2, tempstring1);
  3369.  
  3370.                     strcpy(tempstring1, " ID:                 ");
  3371.                     svalue = getsword(&(contents[which].name[currentpos]));
  3372.                     stcl_d(tempstring2, svalue);
  3373.                     strcat(tempstring1, tempstring2);
  3374.                     if (svalue < 1)
  3375.                     {   strcat(tempstring1, "!");
  3376.                     }
  3377.                     AddNameToTail(&List2, tempstring1);
  3378.                     currentpos += 2;
  3379.  
  3380.                     strcpy(tempstring1, " Position:           ");
  3381.                     uvalue = getulong(&(contents[which].name[currentpos]));
  3382.                     stcl_d(tempstring2, uvalue);
  3383.                     strcat(tempstring1, tempstring2);
  3384.                     AddNameToTail(&List2, tempstring1);
  3385.                     currentpos += 4;
  3386.  
  3387.                     strcpy(tempstring1, " Name:               ");
  3388.                     uvalue = contents[which].name[currentpos++];
  3389.                     // the number of characters in the string
  3390.                     if (uvalue < MEDFIELD)
  3391.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), uvalue);
  3392.                     } else
  3393.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), MEDFIELD);
  3394.                     }
  3395.                     AddNameToTail(&List2, tempstring1);
  3396.                     currentpos += uvalue;
  3397.                     if (uvalue % 2)
  3398.                     {   currentpos++; // skip pad byte, if appropriate
  3399.         }   }   }   }   }
  3400.         elif (!strcmp(contents[which].name, "AESD"))
  3401.         {   chunkdesc("Pertinent to autio recording devices", FALSE);
  3402.         } elif (!strcmp(contents[which].name, "COMT"))
  3403.         {   chunkdesc("Stores comments", TRUE);
  3404.  
  3405.         if (!iff.raw)
  3406.         {
  3407.             strcpy(tempstring1, "Comments:            ");
  3408.             svalue = getsword(contents[which].DataPtr);
  3409.             stcl_d(tempstring2, svalue);
  3410.             strcat(tempstring1, tempstring2);
  3411.             if (svalue < 0)
  3412.             {   strcat(tempstring1, "!");
  3413.             }
  3414.             AddNameToTail(&List2, tempstring1);
  3415.  
  3416.             // we could have a 'comments' variable, but we just reuse
  3417.             // the 'markers' variable.
  3418.             markers = svalue;
  3419.             if (markers > 0)
  3420.             {   currentpos = 2;
  3421.                 for (i = 1; i <= markers; i++)
  3422.                 {   strcpy(tempstring1, "Comment ");
  3423.                     stcl_d(tempstring2, i);
  3424.                     strcat(tempstring1, tempstring2);
  3425.                     strcat(tempstring1, ":");
  3426.                     AddNameToTail(&List2, tempstring1);
  3427.  
  3428.                     strcpy(tempstring1, " Created on:         ");
  3429.                     uvalue = getulong(&(contents[which].DataPtr[currentpos]));
  3430.                     DateTime.dat_Stamp.ds_Days   =   uvalue / 86400;             // days since 1/1/78
  3431.                     DateTime.dat_Stamp.ds_Minute =  (uvalue % 86400) / 60;       // minutes in day
  3432.                     DateTime.dat_Stamp.ds_Tick   = ((uvalue % 86400) % 60) * 50; // ticks in minute
  3433.                     DateTime.dat_Format          = FORMAT_DOS;
  3434.                     DateTime.dat_Flags           = DTF_SUBST;
  3435.                     DateTime.dat_StrDay          = weekdaystring;
  3436.                     DateTime.dat_StrDate         = datestring;
  3437.                     DateTime.dat_StrTime         = timestring;
  3438.                     if (!DateToStr(&DateTime))
  3439.                     {   rq("DateToStr() failed!");
  3440.                     }
  3441.                     strcat(tempstring1, timestring);
  3442.                     strcat(tempstring1, " ");
  3443.                     strcat(tempstring1, weekdaystring);
  3444.                     strcat(tempstring1, " ");
  3445.                     strcat(tempstring1, datestring);
  3446.                     AddNameToTail(&List2, tempstring1);
  3447.                     currentpos += 4;
  3448.  
  3449.                     strcpy(tempstring1, " Marker ID:          ");
  3450.                     svalue = getsword(&(contents[which].DataPtr[currentpos]));
  3451.                     stcl_d(tempstring2, svalue);
  3452.                     strcat(tempstring1, tempstring2);
  3453.                     if (svalue < 1)
  3454.                     {    strcat(tempstring1, "!");
  3455.                     }
  3456.                     AddNameToTail(&List2, tempstring1);
  3457.                     currentpos += 2;
  3458.  
  3459.                     strcpy(tempstring1, " Comment:            ");
  3460.                     uvalue = getuword(&(contents[which].DataPtr[currentpos]));
  3461.                     // the number of characters in the string
  3462.                     currentpos += 2;
  3463.                     if (uvalue < MEDFIELD)
  3464.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), uvalue);
  3465.                     } else
  3466.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), MEDFIELD);
  3467.                     }
  3468.                     AddNameToTail(&List2, tempstring1);
  3469.                     currentpos += uvalue;
  3470.                     if (uvalue % 2)
  3471.                     {   currentpos++; // skip pad byte, if appropriate
  3472.         }   }   }   }   }
  3473.         elif (!strcmp(contents[which].name, "COMM"))
  3474.         {   chunkdesc("Fundamental parameters for the sampled sound", TRUE);
  3475.  
  3476.         if (!iff.raw)
  3477.         {
  3478.             strcpy(tempstring1, "Channels:            ");
  3479.             svalue = getsword(contents[which].DataPtr);
  3480.             stcl_d(tempstring2, svalue);
  3481.             strcat(tempstring1, tempstring2);
  3482.             if (svalue == 1)
  3483.             {   strcat(tempstring1, " (mono)");
  3484.             } elif (svalue == 2)
  3485.             {   strcat(tempstring1, " (stereo)");
  3486.             } elif (svalue > 2)
  3487.             {   strcat(tempstring1, " (surround)");
  3488.             }
  3489.             AddNameToTail(&List2, tempstring1);
  3490.  
  3491.             strcpy(tempstring1, "Sample frames:       ");
  3492.             uvalue = getulong(&(contents[which].DataPtr[2]));
  3493.             stcl_d(tempstring2, uvalue);
  3494.             strcat(tempstring1, tempstring2);
  3495.             AddNameToTail(&List2, tempstring1);
  3496.  
  3497.             strcpy(tempstring1, "Sample quality:      ");
  3498.             svalue = getsword(&(contents[which].DataPtr[6]));
  3499.             stcl_d(tempstring2, svalue);
  3500.             strcat(tempstring1, tempstring2);
  3501.             strcat(tempstring1, "-bit");
  3502.             AddNameToTail(&List2, tempstring1);
  3503.  
  3504.             /* This is an 80-bit IEEE 754 Apple-style (SANE) floating
  3505.             point number (not yet implemented):
  3506.                  79 Sign
  3507.               64:78 Exponent
  3508.                0:63 Mantissa */
  3509.             strcpy(tempstring1, "Playback rate:       -");
  3510.             AddNameToTail(&List2, tempstring1);
  3511.         }   }
  3512.         elif (!strcmp(contents[which].name, "APPL"))
  3513.         {   chunkdesc("Application-specific data", TRUE);
  3514.  
  3515.             if (!iff.raw)
  3516.             {   strcpy(tempstring1, "Application:         ");
  3517.                 strcat(tempstring1, contents[which].DataPtr);
  3518.                 if (!strcmp(tempstring1, "pdos"))
  3519.                 {   strcat(tempstring1, " (Apple II)");
  3520.                 }
  3521.                 AddNameToTail(&List2, tempstring1);
  3522.         }   }
  3523.         elif (!strcmp(contents[which].name, "SSND"))
  3524.         {   chunkdesc("The actual sample frames", TRUE);
  3525.  
  3526.             if (!iff.raw)
  3527.             {   strcpy(tempstring1, "Offset:              ");
  3528.                 uvalue = getulong(contents[which].DataPtr);
  3529.                 stcl_d(tempstring2, uvalue);
  3530.                 strcat(tempstring1, tempstring2);
  3531.                 AddNameToTail(&List2, tempstring1);
  3532.  
  3533.                 strcpy(tempstring1, "Block size:          ");
  3534.                 uvalue = getulong(&(contents[which].DataPtr[4]));
  3535.                 stcl_d(tempstring2, uvalue);
  3536.                 strcat(tempstring1, tempstring2);
  3537.                 AddNameToTail(&List2, tempstring1);
  3538.         }   }
  3539.         elif (!strcmp(contents[which].name, "INST"))
  3540.         {   chunkdesc("Instrument chunk", TRUE);
  3541.  
  3542.         if (!iff.raw)
  3543.         {
  3544.             strcpy(tempstring1, "Base note:           ");
  3545.             svalue = getsbyte(&(contents[which].DataPtr[0]));
  3546.             stcl_d(tempstring2, svalue);
  3547.             strcat(tempstring1, tempstring2);
  3548.             if (svalue < 0 || svalue > 127)
  3549.                 strcat(tempstring1, "!");
  3550.             AddNameToTail(&List2, tempstring1);
  3551.  
  3552.             strcpy(tempstring1, "Detune:              ");
  3553.             svalue = getsbyte(&(contents[which].DataPtr[1]));
  3554.             stcl_d(tempstring2, svalue);
  3555.             strcat(tempstring1, tempstring2);
  3556.             if (svalue < -50 || svalue > 50)
  3557.                 strcat(tempstring1, "!");
  3558.             AddNameToTail(&List2, tempstring1);
  3559.  
  3560.             strcpy(tempstring1, "Low note:            ");
  3561.             svalue = getsbyte(&(contents[which].DataPtr[2]));
  3562.             stcl_d(tempstring2, svalue);
  3563.             strcat(tempstring1, tempstring2);
  3564.             if (svalue < 0 || svalue > 127)
  3565.                 strcat(tempstring1, "!");
  3566.             AddNameToTail(&List2, tempstring1);
  3567.  
  3568.             strcpy(tempstring1, "High note:           ");
  3569.             svalue = getsbyte(&(contents[which].DataPtr[3]));
  3570.             stcl_d(tempstring2, svalue);
  3571.             strcat(tempstring1, tempstring2);
  3572.             if (svalue < 0 || svalue > 127)
  3573.                 strcat(tempstring1, "!");
  3574.             AddNameToTail(&List2, tempstring1);
  3575.  
  3576.             strcpy(tempstring1, "Low velocity:        ");
  3577.             svalue = getsbyte(&(contents[which].DataPtr[4]));
  3578.             stcl_d(tempstring2, svalue);
  3579.             strcat(tempstring1, tempstring2);
  3580.             if (svalue < 1 || svalue > 127)
  3581.                 strcat(tempstring1, "!");
  3582.             AddNameToTail(&List2, tempstring1);
  3583.  
  3584.             strcpy(tempstring1, "High velocity:       ");
  3585.             svalue = getsbyte(&(contents[which].DataPtr[5]));
  3586.             stcl_d(tempstring2, svalue);
  3587.             strcat(tempstring1, tempstring2);
  3588.             if (svalue < 1 || svalue > 127)
  3589.                 strcat(tempstring1, "!");
  3590.             AddNameToTail(&List2, tempstring1);
  3591.  
  3592.             strcpy(tempstring1, "Gain:                ");
  3593.             svalue = getsword(&(contents[which].DataPtr[6]));
  3594.             stcl_d(tempstring2, svalue);
  3595.             strcat(tempstring1, tempstring2);
  3596.             AddNameToTail(&List2, tempstring1);
  3597.  
  3598.             strcpy(tempstring1, "Sustain loop:");
  3599.             svalue = getsword(&(contents[which].DataPtr[8]));
  3600.             if (svalue == 0)
  3601.             {   strcpy(tempstring1, " No looping");
  3602.             } elif (svalue == 1)
  3603.             {   strcpy(tempstring1, " Forwards looping");
  3604.             } elif (svalue == 2)
  3605.             {   strcpy(tempstring1, " Forwards/backwards looping");
  3606.             } else
  3607.             {   strcpy(tempstring1, " ?");
  3608.             }
  3609.             AddNameToTail(&List2, tempstring1);
  3610.             strcpy(tempstring1, " Begin loop:         ");
  3611.             svalue = getsword(&(contents[which].DataPtr[10]));
  3612.             stcl_d(tempstring1, svalue);
  3613.             AddNameToTail(&List2, tempstring1);
  3614.             strcpy(tempstring1, " End loop:           ");
  3615.             svalue = getsword(&(contents[which].DataPtr[12]));
  3616.             stcl_d(tempstring1, svalue);
  3617.             AddNameToTail(&List2, tempstring1);
  3618.  
  3619.             strcpy(tempstring1, "Release loop:        ");
  3620.  
  3621.             svalue = getsword(&(contents[which].DataPtr[14]));
  3622.             if (svalue == 0)
  3623.             {   strcpy(tempstring1, " No looping");
  3624.             } elif (svalue == 1)
  3625.             {   strcpy(tempstring1, " Forwards looping");
  3626.             } elif (svalue == 2)
  3627.             {   strcpy(tempstring1, " Forwards/backwards looping");
  3628.             } else
  3629.             {   strcpy(tempstring1, " ?");
  3630.             }
  3631.             AddNameToTail(&List2, tempstring1);
  3632.             strcpy(tempstring1, " Begin loop:         ");
  3633.             svalue = getsword(&(contents[which].DataPtr[16]));
  3634.             stcl_d(tempstring1, svalue);
  3635.             AddNameToTail(&List2, tempstring1);
  3636.             strcpy(tempstring1, " End loop:           ");
  3637.             svalue = getsword(&(contents[which].DataPtr[18]));
  3638.             stcl_d(tempstring1, svalue);
  3639.             AddNameToTail(&List2, tempstring1);
  3640.     }   }   }
  3641.     elif (!strcmp(queryform, "8SVX"))
  3642.     {   if (!strcmp(contents[which].name, "ATAK"))
  3643.         {   chunkdesc("Gives attack amplitude contour (envelope)", FALSE);
  3644.         } elif (!strcmp(contents[which].name, "RLSE"))
  3645.         {   chunkdesc("Gives release amplitude contour (envelope)", FALSE);
  3646.         } elif (!strcmp(contents[which].name, "BODY"))
  3647.         {   chunkdesc("Sound data chunk", FALSE);
  3648.         } elif (!strcmp(contents[which].name, "FADE"))
  3649.         {   chunkdesc("Fade away to silence", TRUE);
  3650.  
  3651.             if (!iff.raw)
  3652.             {   strcpy(tempstring1, "Fade start:          ");
  3653.                 uvalue = getulong(contents[which].DataPtr);
  3654.                 stcl_d(tempstring2, uvalue);
  3655.                 strcat(tempstring1, tempstring2);
  3656.                 AddNameToTail(&List2, tempstring1);
  3657.         }   }
  3658.         elif (!strcmp(contents[which].name, "SEQN"))
  3659.         {   chunkdesc("Multiple loop sequencing", TRUE);
  3660.  
  3661.         if (!iff.raw)
  3662.         {
  3663.             currentpos = 0;
  3664.             while (currentpos < contents[which].bytes)
  3665.             {   strcpy(tempstring1, "Loop start:          ");
  3666.                 uvalue = getulong(&(contents[which].DataPtr[currentpos]));
  3667.                 stcl_d(tempstring2, uvalue);
  3668.                 strcat(tempstring1, tempstring2);
  3669.                 if (uvalue % 4)
  3670.                 {   strcat(tempstring1, "!");
  3671.                 }
  3672.                 AddNameToTail(&List2, tempstring1);
  3673.                 currentpos += 4;
  3674.  
  3675.                 strcpy(tempstring1, "Loop end:            ");
  3676.                 uvalue = getulong(&(contents[which].DataPtr[currentpos]));
  3677.                 stcl_d(tempstring2, uvalue);
  3678.                 strcat(tempstring1, tempstring2);
  3679.                 if (uvalue % 4)
  3680.                 {   strcat(tempstring1, "!");
  3681.                 }
  3682.                 AddNameToTail(&List2, tempstring1);
  3683.                 currentpos += 4;
  3684.         }   }   }
  3685.         elif (!strcmp(contents[which].name, "CHAN"))
  3686.         {   chunkdesc("Specified channel, or combination of channels", TRUE);
  3687.  
  3688.             if (!iff.raw)
  3689.             {   strcpy(tempstring1, "Channel:             ");
  3690.                 svalue = getslong(contents[which].DataPtr);
  3691.                 if (svalue == 2)
  3692.                 {   strcat(tempstring1, "Left");
  3693.                 } elif (svalue == 4)
  3694.                 {   strcat(tempstring1, "Right");
  3695.                 } elif (svalue == 6)
  3696.                 {   strcat(tempstring1, "Stereo (both)");
  3697.                 } else strcat(tempstring1, "?");
  3698.                 AddNameToTail(&List2, tempstring1);
  3699.         }   }
  3700.         elif (!strcmp(contents[which].name, "PAN "))
  3701.         {   chunkdesc("Stereo sound using a single array of data", TRUE);
  3702.  
  3703.             if (!iff.raw)
  3704.             {   strcpy(tempstring1, "Sound position:      ");
  3705.                 svalue = getslong(contents[which].DataPtr);
  3706.                 stcl_d(tempstring2, svalue);
  3707.                 strcat(tempstring1, tempstring2);
  3708.                 strcat(tempstring1, "/65536 ");
  3709.                 if (svalue < 32768)
  3710.                 {    strcat(tempstring1, "(left)");
  3711.                 } elif (svalue > 32678)
  3712.                 {    strcat(tempstring1, "(right)");
  3713.                 } else
  3714.                 {    // assert(svalue == 32678);
  3715.                      strcat(tempstring1, "(centre)");
  3716.                 }
  3717.                 AddNameToTail(&List2, tempstring1);
  3718.         }   }
  3719.         elif (!strcmp(contents[which].name, "VHDR"))
  3720.         {   chunkdesc("Playback parameters for the sampled waveforms", TRUE);
  3721.  
  3722.             if (!iff.raw)
  3723.             {   strcpy(tempstring1, "1-shot samples:      ");
  3724.                 uvalue = getulong(contents[which].DataPtr);
  3725.                 stcl_d(tempstring2, uvalue);
  3726.                 strcat(tempstring1, tempstring2);
  3727.                 AddNameToTail(&List2, tempstring1);
  3728.  
  3729.                 strcpy(tempstring1, "Repeat samples:      ");
  3730.                 uvalue = getulong(&(contents[which].DataPtr[4]));
  3731.                 stcl_d(tempstring2, uvalue);
  3732.                 strcat(tempstring1, tempstring2);
  3733.                 AddNameToTail(&List2, tempstring1);
  3734.  
  3735.                 strcpy(tempstring1, "Samples per cycle:   ");
  3736.                 uvalue = getulong(&(contents[which].DataPtr[8]));
  3737.                 stcl_d(tempstring2, uvalue);
  3738.                 strcat(tempstring1, tempstring2);
  3739.                 AddNameToTail(&List2, tempstring1);
  3740.  
  3741.                 strcpy(tempstring1, "Sampling rate:       ");
  3742.                 uvalue = getuword(&(contents[which].DataPtr[12]));
  3743.                 stcl_d(tempstring2, uvalue);
  3744.                 strcat(tempstring1, tempstring2);
  3745.                 AddNameToTail(&List2, tempstring1);
  3746.  
  3747.                 strcpy(tempstring1, "Octaves:             ");
  3748.                 uvalue = contents[which].DataPtr[14]; // UBYTE
  3749.                 stcl_d(tempstring2, uvalue);
  3750.                 strcat(tempstring1, tempstring2);
  3751.                 AddNameToTail(&List2, tempstring1);
  3752.  
  3753.                 strcpy(tempstring1, "Compression:         "); // UBYTE
  3754.                 if (contents[which].DataPtr[15] == 0)
  3755.                 {   strcat(tempstring1, "None");
  3756.                 } elif (contents[which].DataPtr[15] == 1)
  3757.                 {   strcat(tempstring1, "Fibonacci-delta encoding");
  3758.                 } else strcat(tempstring1, "?");
  3759.                 AddNameToTail(&List2, tempstring1);
  3760.  
  3761.                 strcpy(tempstring1, "Volume:              ");
  3762.                 svalue = getslong(&(contents[which].DataPtr[16]));
  3763.                 svalue /= 1024; // LONG (Fixed)
  3764.                 stcl_d(tempstring2, svalue);
  3765.                 strcat(tempstring1, tempstring2);
  3766.                 strcat(tempstring1, "/64");
  3767.                 AddNameToTail(&List2, tempstring1);
  3768.     }   }   }
  3769.     elif (!strcmp(queryform, "ILBM") || !strcmp(queryform, "ABCM") || !strcmp(queryform, "ANIM"))
  3770.     {   if (!strcmp(contents[which].name, "CAMG"))
  3771.         {   chunkdesc("Amiga display mode of a picture", TRUE);
  3772.  
  3773.             if (!iff.raw)
  3774.             {   strcpy(tempstring1, "ModeID:             $");
  3775.                 hexalize(contents[which].DataPtr[0]);
  3776.                 hexalize(contents[which].DataPtr[1]);
  3777.                 hexalize(contents[which].DataPtr[2]);
  3778.                 hexalize(contents[which].DataPtr[3]);
  3779.                 AddNameToTail(&List2, tempstring1);
  3780.         }   }
  3781.         elif (!strcmp(queryform, "ANIM") && !strcmp(contents[which].name, "ANHD"))
  3782.         {   chunkdesc("Animation header", TRUE);
  3783.  
  3784.         if (!iff.raw)
  3785.         {
  3786.             strcpy(tempstring1, "Compression method:     ");
  3787.             if (contents[which].DataPtr[0] == 0)
  3788.             {   strcat(tempstring1, "0 (set directly)");
  3789.             } elif (contents[which].DataPtr[0] == 1)
  3790.             {   strcat(tempstring1, "1 (XOR ILBM)");
  3791.             } elif (contents[which].DataPtr[0] == 2)
  3792.             {   strcat(tempstring1, "2 (long delta)");
  3793.             } elif (contents[which].DataPtr[0] == 3)
  3794.             {   strcat(tempstring1, "3 (short delta)");
  3795.             } elif (contents[which].DataPtr[0] == 4)
  3796.             {   strcat(tempstring1, "4 (short/long delta)");
  3797.             } elif (contents[which].DataPtr[0] == 5)
  3798.             {   strcat(tempstring1, "5 (byte vertical delta)");
  3799.             } elif (contents[which].DataPtr[0] == 6)
  3800.             {   strcat(tempstring1, "6 (stereo op 5)");
  3801.             } elif (contents[which].DataPtr[0] == 74) // not a typo
  3802.             {   strcat(tempstring1, "7 (Eric Graham)");
  3803.             } else
  3804.             {   strcat(tempstring1, "?");
  3805.             }
  3806.             AddNameToTail(&List2, tempstring1);
  3807.  
  3808.             strcpy(tempstring1, "Mask:                   %");
  3809.             binarize(contents[which].DataPtr[1]);
  3810.             AddNameToTail(&List2, tempstring1);
  3811.  
  3812.             strcpy(tempstring1, "Entire width:           ");
  3813.             uvalue = getuword(&contents[which].DataPtr[2]); // UWORD
  3814.             stcl_d(tempstring2, uvalue);
  3815.             strcat(tempstring1, tempstring2);
  3816.             strcat(tempstring1, " pixels");
  3817.             AddNameToTail(&List2, tempstring1);
  3818.  
  3819.             strcpy(tempstring1, "Entire height:          ");
  3820.             uvalue = getuword(&contents[which].DataPtr[4]); // UWORD
  3821.             stcl_d(tempstring2, uvalue);
  3822.             strcat(tempstring1, tempstring2);
  3823.             strcat(tempstring1, " pixels");
  3824.             AddNameToTail(&List2, tempstring1);
  3825.  
  3826.             strcpy(tempstring1, "Width:                  ");
  3827.             svalue = getsword(&contents[which].DataPtr[6]); // WORD
  3828.             stcl_d(tempstring2, svalue);
  3829.             strcat(tempstring1, tempstring2);
  3830.             strcat(tempstring1, " pixels");
  3831.             AddNameToTail(&List2, tempstring1);
  3832.  
  3833.             strcpy(tempstring1, "Height:                 ");
  3834.             svalue = getsword(&contents[which].DataPtr[8]); // WORD
  3835.             stcl_d(tempstring2, svalue);
  3836.             strcat(tempstring1, tempstring2);
  3837.             strcat(tempstring1, " pixels");
  3838.             AddNameToTail(&List2, tempstring1);
  3839.  
  3840.             strcpy(tempstring1, "Absolute time:          ");
  3841.             uvalue = getulong(&contents[which].DataPtr[10]); // ULONG
  3842.             stcl_d(tempstring2, uvalue);
  3843.             strcat(tempstring1, tempstring2);
  3844.             strcat(tempstring1, "/60 of a second");
  3845.             AddNameToTail(&List2, tempstring1);
  3846.  
  3847.             strcpy(tempstring1, "Relative time:          ");
  3848.             uvalue = getulong(&contents[which].DataPtr[14]); // ULONG
  3849.             stcl_d(tempstring2, uvalue);
  3850.             strcat(tempstring1, tempstring2);
  3851.             strcat(tempstring1, "/60 of a second");
  3852.             AddNameToTail(&List2, tempstring1);
  3853.  
  3854.             strcpy(tempstring1, "Interleave:             ");
  3855.             if (contents[which].DataPtr[18] == 0)
  3856.             {   strcat(tempstring1, "0 (2 frames back)");
  3857.             } else
  3858.             {   stcl_d(tempstring2, contents[which].DataPtr[18]);
  3859.                 strcat(tempstring1, tempstring2);
  3860.                 strcat(tempstring1, " frames back");
  3861.             }
  3862.             AddNameToTail(&List2, tempstring1);
  3863.  
  3864.             // now a pad byte (19)
  3865.  
  3866.             strcpy(tempstring1, "Flags:");
  3867.             uvalue = getulong(&contents[which].DataPtr[20]); // ULONG
  3868.  
  3869.             strcpy(tempstring1, " Data length:           ");
  3870.             if (uvalue & 1)
  3871.             {   strcat(tempstring1, "Long");
  3872.             } else
  3873.             {   strcat(tempstring1, "Short");
  3874.             }
  3875.             AddNameToTail(&List2, tempstring1);
  3876.  
  3877.             strcpy(tempstring1, " Set/XOR:               ");
  3878.             if (uvalue & 2)
  3879.             {   strcat(tempstring1, "Set");
  3880.             } else
  3881.             {   strcat(tempstring1, "XOR");
  3882.             }
  3883.             AddNameToTail(&List2, tempstring1);
  3884.  
  3885.             strcpy(tempstring1, " Info:                  ");
  3886.             if (uvalue & 4)
  3887.             {   strcat(tempstring1, "One info list for all planes");
  3888.             } else
  3889.             {   strcat(tempstring1, "Separate info for each plane");
  3890.             }
  3891.             AddNameToTail(&List2, tempstring1);
  3892.  
  3893.             strcpy(tempstring1, " Run length encoded?    ");
  3894.             if (uvalue & 8)
  3895.             {   strcat(tempstring1, "Yes");
  3896.             } else
  3897.             {   strcat(tempstring1, "No");
  3898.             }
  3899.             AddNameToTail(&List2, tempstring1);
  3900.  
  3901.             strcpy(tempstring1, " Encoding:              ");
  3902.             if (uvalue & 16)
  3903.             {   strcat(tempstring1, "Vertical");
  3904.             } else
  3905.             {   strcat(tempstring1, "Horizontal");
  3906.             }
  3907.             AddNameToTail(&List2, tempstring1);
  3908.  
  3909.             strcpy(tempstring1, " Info offsets:          ");
  3910.             if (uvalue & 32)
  3911.             {   strcat(tempstring1, "Short");
  3912.             } else
  3913.             {   strcat(tempstring1, "Long");
  3914.             }
  3915.             AddNameToTail(&List2, tempstring1);
  3916.  
  3917.             // now 16 reserved bytes
  3918.         }   }
  3919.         elif (!strcmp(queryform, "ANIM") && !strcmp(contents[which].name, "DLTA"))
  3920.         {   chunkdesc("Delta compression data", FALSE);
  3921.         } elif (!strcmp(contents[which].name, "DPI "))
  3922.         {   chunkdesc("Dots per inch", TRUE);
  3923.  
  3924.             if (!iff.raw)
  3925.             {   strcpy(tempstring1, "Dots per inch:      ");
  3926.                 // There are 20 characters in the first column.
  3927.                 uvalue = getuword(contents[which].DataPtr);
  3928.                 stcl_d(tempstring2, uvalue);
  3929.                 strcat(tempstring1, tempstring2);
  3930.                 strcat(tempstring1, "x");
  3931.                 uvalue = getuword(&(contents[which].DataPtr[2]));
  3932.                 stcl_d(tempstring2, uvalue);
  3933.                 strcat(tempstring1, tempstring2);
  3934.                 AddNameToTail(&List2, tempstring1);
  3935.         }   }
  3936.         elif (!strcmp(contents[which].name, "CMAP"))
  3937.         {   chunkdesc("Colour map data", FALSE);
  3938.         } elif (!strcmp(contents[which].name, "BODY"))
  3939.         {   chunkdesc("Image data chunk", FALSE);
  3940.         } elif (!strcmp(contents[which].name, "EPSF"))
  3941.         {   chunkdesc("Encapsulated PostScript representation of image", TRUE);
  3942.  
  3943.         if (!iff.raw)
  3944.         {
  3945.             strcpy(tempstring1, "Left X:             ");
  3946.             svalue = getsword(contents[which].DataPtr);
  3947.             stcl_d(tempstring2, svalue);
  3948.             strcat(tempstring1, tempstring2);
  3949.             AddNameToTail(&List2, tempstring1);
  3950.  
  3951.             strcpy(tempstring1, "Top Y:              ");
  3952.             svalue = getsword(&(contents[which].DataPtr[2]));
  3953.             stcl_d(tempstring2, svalue);
  3954.             strcat(tempstring1, tempstring2);
  3955.             AddNameToTail(&List2, tempstring1);
  3956.  
  3957.             strcpy(tempstring1, "Right X:            ");
  3958.             svalue = getsword(&(contents[which].DataPtr[4]));
  3959.             stcl_d(tempstring2, svalue);
  3960.             strcat(tempstring1, tempstring2);
  3961.             AddNameToTail(&List2, tempstring1);
  3962.  
  3963.             strcpy(tempstring1, "Bottom Y:           ");
  3964.             svalue = getsword(&(contents[which].DataPtr[6]));
  3965.             stcl_d(tempstring2, svalue);
  3966.             strcat(tempstring1, tempstring2);
  3967.             AddNameToTail(&List2, tempstring1);
  3968.         }   }
  3969.         elif (!strcmp(contents[which].name, "DEST"))
  3970.         {   chunkdesc("Scatter bitplanes into a deeper destination image", TRUE);
  3971.  
  3972.         if (!iff.raw)
  3973.         {
  3974.             strcpy(tempstring1, "Source bitplanes:   ");
  3975.             stcl_d(tempstring2, contents[which].DataPtr[0]);
  3976.             strcat(tempstring1, tempstring2);
  3977.             AddNameToTail(&List2, tempstring1);
  3978.  
  3979.             // next (1) is a pad byte.
  3980.  
  3981.             strcpy(tempstring1, "PlanePick:          %"); // UWORD
  3982.             binarize(contents[which].DataPtr[2]);
  3983.             binarize(contents[which].DataPtr[3]);
  3984.             AddNameToTail(&List2, tempstring1);
  3985.  
  3986.             strcpy(tempstring1, "PlaneOnOff:         %"); // UWORD
  3987.             binarize(contents[which].DataPtr[4]);
  3988.             binarize(contents[which].DataPtr[5]);
  3989.             AddNameToTail(&List2, tempstring1);
  3990.  
  3991.             strcpy(tempstring1, "PlaneMask:          %"); // UWORD
  3992.             binarize(contents[which].DataPtr[6]);
  3993.             binarize(contents[which].DataPtr[7]);
  3994.             AddNameToTail(&List2, tempstring1);
  3995.         }   }
  3996.         elif (!strcmp(contents[which].name, "GRAB"))
  3997.         {   chunkdesc("Locates a hotspot, when used as a pointer or brush", TRUE);
  3998.  
  3999.             if (!iff.raw)
  4000.             {   strcpy(tempstring1, "Hotspot:            ");
  4001.                 svalue = getsword(contents[which].DataPtr);
  4002.                 stcl_d(tempstring2, svalue);
  4003.                 strcat(tempstring1, tempstring2);
  4004.                 strcat(tempstring1, ",");
  4005.                 svalue = getsword(&(contents[which].DataPtr[2]));
  4006.                 stcl_d(tempstring2, svalue);
  4007.                 strcat(tempstring1, tempstring2);
  4008.                 AddNameToTail(&List2, tempstring1);
  4009.         }   }
  4010.         elif (!strcmp(contents[which].name, "SPRT"))
  4011.         {   chunkdesc("This image is intended as a sprite", TRUE);
  4012.  
  4013.             if (!iff.raw)
  4014.             {   strcpy(tempstring1, "Precedence:         ");
  4015.                 uvalue = getuword(contents[which].DataPtr);
  4016.  
  4017.                 stcl_d(tempstring2, uvalue);
  4018.                 strcat(tempstring1, tempstring2);
  4019.                 AddNameToTail(&List2, tempstring1);
  4020.         }   }
  4021.         elif (!strcmp(contents[which].name, "BMHD"))
  4022.         {   /* UWORD w, h;               0-1, 2-3
  4023.             WORD  x, y;                  4-5, 6-7
  4024.             UBYTE nPlanes;               8
  4025.             UBYTE Masking;               9
  4026.             UBYTE Compression;           10
  4027.             UBYTE pad;                   11
  4028.             UWORD transparentColour;     12-13
  4029.             UBYTE xAspect, yAspect;      14, 15
  4030.             WORD  pageWidth, pageHeight; 16-17, 18-19 */
  4031.  
  4032.             chunkdesc("Data necessary to understand the BODY chunk", TRUE);
  4033.  
  4034.             if (!iff.raw)
  4035.             {
  4036.             strcpy(tempstring1, "Image size:         ");
  4037.             stcl_d(tempstring2, (256 * contents[which].DataPtr[0])
  4038.                               +        contents[which].DataPtr[1]); // UWORD
  4039.             strcat(tempstring1, tempstring2);
  4040.             strcat(tempstring1, "x");
  4041.             stcl_d(tempstring2, (256 * contents[which].DataPtr[2])
  4042.                               +        contents[which].DataPtr[3]); // UWORD
  4043.             strcat(tempstring1, tempstring2);
  4044.             AddNameToTail(&List2, tempstring1);
  4045.  
  4046.             strcpy(tempstring1, "Position:           ");
  4047.             stcl_d(tempstring2, (256 * contents[which].DataPtr[4])
  4048.                               +        contents[which].DataPtr[5]); // WORD
  4049.             strcat(tempstring1, tempstring2);
  4050.             strcat(tempstring1, ",");
  4051.             stcl_d(tempstring2, (256 * contents[which].DataPtr[6])
  4052.                               +        contents[which].DataPtr[7]); // WORD
  4053.             strcat(tempstring1, tempstring2);
  4054.             AddNameToTail(&List2, tempstring1);
  4055.  
  4056.             strcpy(tempstring1, "Bitplanes:          ");
  4057.             stcl_d(tempstring2, (LONG) contents[which].DataPtr[8]);
  4058.             strcat(tempstring1, tempstring2);
  4059.             AddNameToTail(&List2, tempstring1);
  4060.             // tell number of colours to user?
  4061.  
  4062.             strcpy(tempstring1, "Masking:            ");
  4063.             if (contents[which].DataPtr[9] == 0)
  4064.             {   strcat(tempstring1, "0 (Opaque)");
  4065.             } elif (contents[which].DataPtr[9] == 1)
  4066.             {   strcat(tempstring1, "1 (Mask plane)");
  4067.             } elif (contents[which].DataPtr[9] == 2)
  4068.             {   strcat(tempstring1, "2 (Transparent colour)");
  4069.             } elif (contents[which].DataPtr[9] == 3)
  4070.             {   strcat(tempstring1, "3 (Lasso)");
  4071.             } else strcat(tempstring1, "?");
  4072.             AddNameToTail(&List2, tempstring1);
  4073.  
  4074.             strcpy(tempstring1, "Compression:        ");
  4075.             if (contents[which].DataPtr[10] == 0)
  4076.             {   strcat(tempstring1, "None");
  4077.             } elif (contents[which].DataPtr[10] == 1)
  4078.             {   strcat(tempstring1, "Byte run encoding");
  4079.             } else strcat(tempstring1, "?");
  4080.             AddNameToTail(&List2, tempstring1);
  4081.  
  4082.             // Next (11) is a pad byte.
  4083.  
  4084.             strcpy(tempstring1, "Transparent colour: ");
  4085.             if (contents[which].DataPtr[9] != 2
  4086.              && contents[which].DataPtr[9] != 3)
  4087.             {   strcat(tempstring1, "n/a");
  4088.             } else
  4089.             {   stcl_d(tempstring2, (256 * contents[which].DataPtr[12])
  4090.                                   +        contents[which].DataPtr[13]);
  4091.                 strcat(tempstring1, tempstring2);
  4092.             }
  4093.             AddNameToTail(&List2, tempstring1);
  4094.  
  4095.             strcpy(tempstring1, "Aspect ratio:       ");
  4096.             stcl_d(tempstring2, (UBYTE) contents[which].DataPtr[14]);
  4097.             strcat(tempstring1, tempstring2);
  4098.             strcat(tempstring1, ":");
  4099.             stcl_d(tempstring2, (UBYTE) contents[which].DataPtr[15]);
  4100.             strcat(tempstring1, tempstring2);
  4101.             AddNameToTail(&List2, tempstring1);
  4102.  
  4103.             strcpy(tempstring1, "Page size:          ");
  4104.             stcl_d(tempstring2, (256 * contents[which].DataPtr[16])
  4105.                               +        contents[which].DataPtr[17]); // WORD
  4106.             strcat(tempstring1, tempstring2);
  4107.             strcat(tempstring1, "x");
  4108.             stcl_d(tempstring2, (256 * contents[which].DataPtr[18])
  4109.                               +        contents[which].DataPtr[19]); // WORD
  4110.             strcat(tempstring1, tempstring2);
  4111.             AddNameToTail(&List2, tempstring1);
  4112.     }   }   }
  4113.  
  4114.     if (!known || iff.raw)
  4115.     {   for (i = 0; i < contents[which].bytes; i += BYTESPERLINE)
  4116.         {   strcpy(tempstring1, "$");
  4117.  
  4118.             hexalize(i / 16777216); // do 1st byte
  4119.             j = i % 16777216;       // remove 1st byte
  4120.             hexalize(j / 65536);    // do 2nd byte
  4121.             j %= 65536;             // remove 2nd byte
  4122.             hexalize(j / 256);      // do 3rd byte
  4123.             hexalize(j % 256);      // do 4th byte
  4124.  
  4125.             strcat(tempstring1, ": ");
  4126.             for (j = 0; j < BYTESPERLINE; j++)
  4127.             {   if (contents[which].bytes > i + j)
  4128.                 {   hexalize(contents[which].DataPtr[i + j]);
  4129.                 } else
  4130.                 {   strcat(tempstring1, "##");
  4131.                 }
  4132.                 if (j % 2)
  4133.                 {   strcat(tempstring1, " ");
  4134.             }   }
  4135.             for (j = 0; j < BYTESPERLINE; j++)
  4136.             {   if (contents[which].bytes > i + j)
  4137.                 {   if (contents[which].DataPtr[i + j] < ' ') // if an unprintable character
  4138.                     {   strcat(tempstring1, ".");
  4139.                     } else
  4140.                     {   length = strlen(tempstring1);
  4141.                         tempstring1[length] = contents[which].DataPtr[i + j];
  4142.                         tempstring1[length + 1] = 0;
  4143.                 }   }
  4144.                 else
  4145.                 {   strcat(tempstring1, "#");
  4146.             }   }
  4147.             AddNameToTail(&List2, tempstring1);
  4148.     }   }
  4149.     if (!known)
  4150.     {   chunkdesc("?", FALSE);
  4151.     }
  4152.  
  4153.     GT_SetGadgetAttrs
  4154.     (   LV61_List2,
  4155.         MainWindowPtr,
  4156.         NULL,
  4157.         GTLV_Labels, &List2,
  4158.         TAG_DONE
  4159.     );
  4160. }
  4161.  
  4162. MODULE void chunkdesc(STRPTR desc, ABOOL isknown)
  4163. {   GT_SetGadgetAttrs
  4164.     (   TE61_ChunkDesc,
  4165.         MainWindowPtr,
  4166.         NULL,
  4167.         GTTX_Text, desc,
  4168.         TAG_DONE
  4169.     );
  4170.     known = isknown;
  4171. }
  4172.  
  4173. MODULE void binarize(UBYTE data)
  4174. {   SLONG i; // must be signed
  4175.  
  4176.     for (i = 7; i >= 0; i--)
  4177.     {   if (data & (1 << i))
  4178.         {   strcat(tempstring1, "1");
  4179.         } else
  4180.         {   strcat(tempstring1, "0");
  4181. }   }   }
  4182.  
  4183. MODULE void hexalize(UBYTE data)
  4184. {   // Converts an unsigned byte into a hexadecimal string
  4185.  
  4186.     // do the high byte
  4187.     if (data / 16 >= 10)
  4188.     {   tempstring2[0] = (data / 16) - 10 + 'A'; // must be done in this order to prevent overflow during calculation of the value
  4189.     } else
  4190.     {   tempstring2[0] = (data / 16) + '0';
  4191.     }
  4192.  
  4193.     // now the low byte
  4194.     if (data % 16 >= 10)
  4195.     {   tempstring2[1] = (data % 16) - 10 + 'A';
  4196.     } else
  4197.     {   tempstring2[1] = (data % 16) + '0';
  4198.     }
  4199.     tempstring2[2] = 0;
  4200.     strcat(tempstring1, tempstring2);
  4201. }
  4202.  
  4203. MODULE ULONG getulong(UBYTE* start)
  4204. {   return (ULONG) ((16777216 * *(start    ))
  4205.                   + (   65536 * *(start + 1))
  4206.                   + (     256 * *(start + 2))
  4207.                   +             *(start + 3));
  4208. }
  4209. MODULE SLONG getslong(UBYTE* start)
  4210. {   return (SLONG) ((16777216 * *(start    ))
  4211.                   + (   65536 * *(start + 1))
  4212.                   + (     256 * *(start + 2))
  4213.                   +             *(start + 3));
  4214. }
  4215. MODULE ULONG getuword(UBYTE* start)
  4216. {   return (ULONG) ((     256 * *(start    ))
  4217.                   +             *(start + 1));
  4218. }
  4219. MODULE SLONG getsword(UBYTE* start)
  4220. {   return (SLONG) ((     256 * *(start    ))
  4221.                   +             *(start + 1));
  4222. }
  4223. MODULE SLONG getsbyte(UBYTE* start)
  4224. {   return (SBYTE) (*start);
  4225. }
  4226.  
  4227. MODULE void writeiffgadgets(void)
  4228. {   // update the gadgets according to variables
  4229.  
  4230.     GT_SetGadgetAttrs
  4231.     (   CB61_CD,
  4232.         MainWindowPtr,
  4233.         NULL,
  4234.         GTCB_Checked, iff.cd,
  4235.         TAG_DONE
  4236.     );
  4237.     GT_SetGadgetAttrs
  4238.     (   CB61_RKM,
  4239.         MainWindowPtr,
  4240.         NULL,
  4241.         GTCB_Checked, iff.rkm,
  4242.         TAG_DONE
  4243.     );
  4244.     GT_SetGadgetAttrs
  4245.     (   CB61_Obsolete,
  4246.         MainWindowPtr,
  4247.         NULL,
  4248.         GTCB_Checked, iff.obsolete,
  4249.         TAG_DONE
  4250.     );
  4251.     GT_SetGadgetAttrs
  4252.     (   CB61_Private,
  4253.         MainWindowPtr,
  4254.         NULL,
  4255.         GTCB_Checked, iff.private,
  4256.         TAG_DONE
  4257.     );
  4258.     GT_SetGadgetAttrs
  4259.     (   CB61_Proposal,
  4260.         MainWindowPtr,
  4261.         NULL,
  4262.         GTCB_Checked, iff.proposal,
  4263.         TAG_DONE
  4264.     );
  4265.     GT_SetGadgetAttrs
  4266.     (   CB61_Reserved,
  4267.         MainWindowPtr,
  4268.         NULL,
  4269.         GTCB_Checked, iff.reserved,
  4270.         TAG_DONE
  4271.     );
  4272.     GT_SetGadgetAttrs
  4273.     (   CB61_Standard,
  4274.         MainWindowPtr,
  4275.         NULL,
  4276.         GTCB_Checked, iff.standard,
  4277.         TAG_DONE
  4278.     );
  4279.     GT_SetGadgetAttrs
  4280.     (   CB61_Unregistered,
  4281.         MainWindowPtr,
  4282.         NULL,
  4283.         GTCB_Checked, iff.unregistered,
  4284.         TAG_DONE
  4285.     );
  4286.     GT_SetGadgetAttrs
  4287.     (   ST61_FORMID,
  4288.         MainWindowPtr,
  4289.         NULL,
  4290.         GTST_String, queryform,
  4291.         TAG_DONE
  4292.     );
  4293.     chunkdesc("-", FALSE);
  4294. }
  4295.  
  4296. MODULE void dotextattr(UBYTE* offset)
  4297. {   ULONG uvalue;
  4298.  
  4299.     // handles TextAttr structure (8 bytes)
  4300.     // name pointer is ignored
  4301.  
  4302.             strcpy(tempstring1, " Height:                ");
  4303.             uvalue = getuword(offset + 4);
  4304.             stcl_d(tempstring2, uvalue);
  4305.             strcat(tempstring1, tempstring2);
  4306.             AddNameToTail(&List2, tempstring1);
  4307.  
  4308.             AddNameToTail(&List2, " Style:");
  4309.  
  4310.             strcpy(tempstring1, "  Underlined?           ");
  4311.             if ((*(offset + 6)) &   1) // FSF_UNDERLINED
  4312.             {   strcat(tempstring1, "Yes");
  4313.             } else
  4314.             {   strcat(tempstring1, "No");
  4315.             }
  4316.             AddNameToTail(&List2, tempstring1);
  4317.  
  4318.             strcpy(tempstring1, "  Bold?                 ");
  4319.             if (*(offset + 6) &   2) // FSF_BOLD
  4320.             {   strcat(tempstring1, "Yes");
  4321.             } else
  4322.             {   strcat(tempstring1, "No");
  4323.             }
  4324.             AddNameToTail(&List2, tempstring1);
  4325.  
  4326.             strcpy(tempstring1, "  Italic?               ");
  4327.             if (*(offset + 6) &   4) // FSF_UNDERLINED
  4328.             {   strcat(tempstring1, "Yes");
  4329.             } else
  4330.             {   strcat(tempstring1, "No");
  4331.             }
  4332.             AddNameToTail(&List2, tempstring1);
  4333.  
  4334.             strcpy(tempstring1, "  Extended?             ");
  4335.             if (*(offset + 6) &   8) // FSF_EXTENDED
  4336.             {   strcat(tempstring1, "Yes");
  4337.             } else
  4338.             {   strcat(tempstring1, "No");
  4339.             }
  4340.             AddNameToTail(&List2, tempstring1);
  4341.  
  4342.             strcpy(tempstring1, "  Colour font?          ");
  4343.             if (*(offset + 6) &  64) // FSF_COLORFONT
  4344.             {   strcat(tempstring1, "Yes");
  4345.             } else
  4346.             {   strcat(tempstring1, "No");
  4347.             }
  4348.             AddNameToTail(&List2, tempstring1);
  4349.  
  4350.             strcpy(tempstring1, "  Tagged?               ");
  4351.             if (*(offset + 6) & 128) // FSF_TAGGED
  4352.             {   strcat(tempstring1, "Yes");
  4353.             } else
  4354.             {   strcat(tempstring1, "No");
  4355.             }
  4356.             AddNameToTail(&List2, tempstring1);
  4357.  
  4358.             AddNameToTail(&List2, " Flags:");
  4359.  
  4360.             strcpy(tempstring1, "  ROM font?             ");
  4361.             if (*(offset + 7) &   1) // FPF_ROMFONT
  4362.             {   strcat(tempstring1, "Yes");
  4363.             } else
  4364.             {   strcat(tempstring1, "No");
  4365.             }
  4366.             AddNameToTail(&List2, tempstring1);
  4367.  
  4368.             strcpy(tempstring1, "  Disk font?            ");
  4369.             if (*(offset + 7) &   2) // FPF_DISKFONT
  4370.             {   strcat(tempstring1, "Yes");
  4371.             } else
  4372.             {   strcat(tempstring1, "No");
  4373.             }
  4374.             AddNameToTail(&List2, tempstring1);
  4375.  
  4376.             strcpy(tempstring1, "  Reversed?             ");
  4377.             if (*(offset + 7) &   4) // FPF_REVPATH
  4378.             {   strcat(tempstring1, "Yes");
  4379.             } else
  4380.             {   strcat(tempstring1, "No");
  4381.             }
  4382.             AddNameToTail(&List2, tempstring1);
  4383.  
  4384.             strcpy(tempstring1, "  HiRes non-interlaced? ");
  4385.             if (*(offset + 7) &   8) // FPF_TALLDOT
  4386.             {   strcat(tempstring1, "Yes");
  4387.             } else
  4388.             {   strcat(tempstring1, "No");
  4389.             }
  4390.             AddNameToTail(&List2, tempstring1);
  4391.  
  4392.     strcpy(tempstring1, "  LoRes interlaced?     ");
  4393.     if (*(offset + 7) &  16) // FPF_WIDEDOT
  4394.     {   strcat(tempstring1, "Yes");
  4395.     } else
  4396.     {   strcat(tempstring1, "No");
  4397.     }
  4398.     AddNameToTail(&List2, tempstring1);
  4399.  
  4400.     strcpy(tempstring1, "  Proportional?         ");
  4401.     if (*(offset + 7) &  32) // FPF_PROPORTIONAL
  4402.     {   strcat(tempstring1, "Yes");
  4403.     } else
  4404.     {   strcat(tempstring1, "No");
  4405.     }
  4406.     AddNameToTail(&List2, tempstring1);
  4407.  
  4408.     strcpy(tempstring1, "  Designed?             ");
  4409.     if (*(offset + 7) &  64) // FPF_DESIGNED
  4410.     {   strcat(tempstring1, "Yes");
  4411.     } else
  4412.     {   strcat(tempstring1, "No");
  4413.     }
  4414.     AddNameToTail(&List2, tempstring1);
  4415.  
  4416.     strcpy(tempstring1, "  Removed?              ");
  4417.     if (*(offset + 7) & 128) // FPF_REMOVED
  4418.     {   strcat(tempstring1, "Yes!");
  4419.     } else
  4420.     {   strcat(tempstring1, "No");
  4421.     }
  4422.     AddNameToTail(&List2, tempstring1);
  4423. }
  4424.  
  4425. MODULE void docountry(UBYTE* offset)
  4426. {   ULONG uvalue;
  4427.  
  4428.     // handles CountryPrefs structure (8 bytes)
  4429.  
  4430.     // 16 reserved bytes at start
  4431.  
  4432.     strcpy(tempstring1, "Country code:           ");
  4433.     uvalue = getulong(offset + 16); // ULONG
  4434.     stcl_d(tempstring2, uvalue);
  4435.     strcat(tempstring1, tempstring2);
  4436.     AddNameToTail(&List2, tempstring1);
  4437.  
  4438.     strcpy(tempstring1, "Telephone code:         ");
  4439.     uvalue = getulong(offset + 20); // ULONG
  4440.     stcl_d(tempstring2, uvalue);
  4441.     strcat(tempstring1, tempstring2);
  4442.     AddNameToTail(&List2, tempstring1);
  4443.  
  4444.     strcpy(tempstring1, "Measuring system:       ");
  4445.     if (*(offset + 24) == 0) // MS_ISO
  4446.     {   strcat(tempstring1, "0 (Metric)");
  4447.     } elif (*(offset + 24) == 1) // MS_AMERICAN
  4448.     {   strcat(tempstring1, "1 (American)");
  4449.     } elif (*(offset + 24) == 2) // MS_IMPERIAL
  4450.     {   strcat(tempstring1, "2 (Imperial)");
  4451.     } elif (*(offset + 24) == 3) // MS_BRITISH
  4452.     {   strcat(tempstring1, "3 (British)");
  4453.     } else
  4454.     {   strcat(tempstring1, "?");
  4455.     }
  4456.     AddNameToTail(&List2, tempstring1);
  4457.  
  4458.     strcpy(tempstring1, "Long date/time format:  ");
  4459.     strcat(tempstring1, offset + 25); // 80 chars
  4460.     AddNameToTail(&List2, tempstring1);
  4461.  
  4462.     strcpy(tempstring1, "Long date format:       ");
  4463.     strcat(tempstring1, offset + 105); // 40 chars
  4464.     AddNameToTail(&List2, tempstring1);
  4465.  
  4466.     strcpy(tempstring1, "Long time format:       ");
  4467.     strcat(tempstring1, offset + 145); // 40 chars
  4468.     AddNameToTail(&List2, tempstring1);
  4469.  
  4470.     strcpy(tempstring1, "Short date/time format: ");
  4471.     strcat(tempstring1, offset + 185); // 80 chars
  4472.     AddNameToTail(&List2, tempstring1);
  4473.  
  4474.     strcpy(tempstring1, "Short date format:      ");
  4475.     strcat(tempstring1, offset + 225); // 40 chars
  4476.     AddNameToTail(&List2, tempstring1);
  4477.  
  4478.     strcpy(tempstring1, "Short time format:      ");
  4479.     strcat(tempstring1, offset + 265); // 40 chars
  4480.     AddNameToTail(&List2, tempstring1);
  4481.  
  4482.     AddNameToTail(&List2, "Numeric values:");
  4483.  
  4484.     strcpy(tempstring1, " Decimal point:         ");
  4485.     strcat(tempstring1, offset + 305); // 10 chars
  4486.     AddNameToTail(&List2, tempstring1);
  4487.  
  4488.     strcpy(tempstring1, " Intgr group separator: ");
  4489.     strcat(tempstring1, offset + 315); // 10 chars
  4490.     AddNameToTail(&List2, tempstring1);
  4491.  
  4492.     strcpy(tempstring1, " Frac. group separator: ");
  4493.     strcat(tempstring1, offset + 325); // 10 chars
  4494.     AddNameToTail(&List2, tempstring1);
  4495.  
  4496.     /* Integer group size (10 chars) and
  4497.        Fractional group size (10 chars): not strings (currently skipped */
  4498.  
  4499.     AddNameToTail(&List2, "General monetary values:");
  4500.  
  4501.     strcpy(tempstring1, " Decimal point:         ");
  4502.     strcat(tempstring1, offset + 355); // 10 chars
  4503.     AddNameToTail(&List2, tempstring1);
  4504.  
  4505.     strcpy(tempstring1, " Intgr group separator: ");
  4506.     strcat(tempstring1, offset + 365); // 10 chars
  4507.     AddNameToTail(&List2, tempstring1);
  4508.  
  4509.     strcpy(tempstring1, " Frac. group separator: ");
  4510.     strcat(tempstring1, offset + 375); // 10 chars
  4511.     AddNameToTail(&List2, tempstring1);
  4512.  
  4513.     /* Integer group size (10 chars) and
  4514.        Fractional group size (10 chars): not strings (currently skipped */
  4515.  
  4516.     AddNameToTail(&List2, " Digits after decimal point:");
  4517.  
  4518.     strcpy(tempstring1, "  Intranational:        ");
  4519.     stcl_d(tempstring2, *(offset + 405));
  4520.     strcat(tempstring1, tempstring2);
  4521.     AddNameToTail(&List2, tempstring1);
  4522.     strcpy(tempstring1, "  International:        ");
  4523.     stcl_d(tempstring2, *(offset + 406));
  4524.     strcat(tempstring1, tempstring2);
  4525.     AddNameToTail(&List2, tempstring1);
  4526.  
  4527.     AddNameToTail(&List2, "Currency symbols:");
  4528.  
  4529.     strcpy(tempstring1, " Large amounts symbol:  ");
  4530.     strcat(tempstring1, offset + 407); // 10 chars
  4531.     AddNameToTail(&List2, tempstring1);
  4532.  
  4533.     strcpy(tempstring1, " Small amounts symbol:  ");
  4534.     strcat(tempstring1, offset + 417); // 10 chars
  4535.     AddNameToTail(&List2, tempstring1);
  4536.  
  4537.     strcpy(tempstring1, " ISO 4217 code:         ");
  4538.     strcat(tempstring1, offset + 427); // 10 chars
  4539.     AddNameToTail(&List2, tempstring1);
  4540.  
  4541.     AddNameToTail(&List2, "Positive monetary values:");
  4542.  
  4543.     strcpy(tempstring1, " Positive sign:         ");
  4544.     strcat(tempstring1, offset + 437); // 10 chars
  4545.     AddNameToTail(&List2, tempstring1);
  4546.  
  4547.     strcpy(tempstring1, " Space next to sign?    ");
  4548.     if (*(offset + 447) == 0) // SS_NOSPACE
  4549.     {   strcat(tempstring1, "No");
  4550.     } elif (*(offset + 447) == 1) // SS_SPACE
  4551.     {   strcat(tempstring1, "Yes");
  4552.     } else strcat(tempstring1, "?");
  4553.     AddNameToTail(&List2, tempstring1);
  4554.  
  4555.     strcpy(tempstring1, " Positive sign pos.:    ");
  4556.     if (*(offset + 448) == 0) // SP_PARENS
  4557.     {   strcat(tempstring1, "0 (parentheses around amount and symbol)");
  4558.     } elif (*(offset + 448) == 1) // SP_PREC_ALL
  4559.     {   strcat(tempstring1, "1 (sign is before amount and symbol)");
  4560.     } elif (*(offset + 448) == 2) // SP_SUCC_ALL
  4561.     {   strcat(tempstring1, "2 (sign is after amount and symbol)");
  4562.     } elif (*(offset + 448) == 3) // SP_PREC_CURR
  4563.     {   strcat(tempstring1, "3 (sign is before symbol)");
  4564.     } elif (*(offset + 448) == 4) // SP_SUCC_CURR
  4565.     {   strcat(tempstring1, "4 (sign is after symbol)");
  4566.     } else
  4567.     {   strcat(tempstring1, "?");
  4568.     }
  4569.     AddNameToTail(&List2, tempstring1);
  4570.  
  4571.     strcpy(tempstring1, " Currency symbol pos.:  ");
  4572.     if (*(offset + 449) == 0) // CSP_PRECEDES
  4573.     {   strcat(tempstring1, "0 (symbol is before amount)");
  4574.     } elif (*(offset + 449) == 1) // CSP_SUCCEEDS
  4575.     {   strcat(tempstring1, "1 (symbol is after amount)");
  4576.     } else
  4577.     {   strcat(tempstring1, "?");
  4578.     }
  4579.     AddNameToTail(&List2, tempstring1);
  4580.  
  4581.     AddNameToTail(&List2, "Negative monetary values:");
  4582.  
  4583.     strcpy(tempstring1, " Negative sign:         ");
  4584.     strcat(tempstring1, offset + 450); // 10 chars
  4585.     AddNameToTail(&List2, tempstring1);
  4586.  
  4587.     strcpy(tempstring1, " Space next to sign?    ");
  4588.     if (*(offset + 460) == 0) // SS_NOSPACE
  4589.     {   strcat(tempstring1, "No");
  4590.     } elif (*(offset + 460) == 1) // SS_SPACE
  4591.     {   strcat(tempstring1, "Yes");
  4592.     } else strcat(tempstring1, "?");
  4593.     AddNameToTail(&List2, tempstring1);
  4594.  
  4595.     strcpy(tempstring1, " Negative sign pos.:    ");
  4596.     if (*(offset + 461) == 0) // SP_PARENS
  4597.     {   strcat(tempstring1, "0 (parentheses around amount and symbol)");
  4598.     } elif (*(offset + 461) == 1) // SP_PREC_ALL
  4599.     {   strcat(tempstring1, "1 (sign is before amount and symbol)");
  4600.     } elif (*(offset + 461) == 2) // SP_SUCC_ALL
  4601.     {   strcat(tempstring1, "2 (sign is after amount and symbol)");
  4602.     } elif (*(offset + 461) == 3) // SP_PREC_CURR
  4603.     {   strcat(tempstring1, "3 (sign is before symbol)");
  4604.     } elif (*(offset + 461) == 4) // SP_SUCC_CURR
  4605.     {   strcat(tempstring1, "4 (sign is after symbol)");
  4606.     } else
  4607.     {   strcat(tempstring1, "?");
  4608.     }
  4609.     AddNameToTail(&List2, tempstring1);
  4610.  
  4611.     strcpy(tempstring1, " Currency symbol pos.:  ");
  4612.     if (*(offset + 462) == 0) // CSP_PRECEDES
  4613.     {   strcat(tempstring1, "0 (symbol is before amount)");
  4614.     } elif (*(offset + 462) == 1) // CSP_SUCCEEDS
  4615.     {   strcat(tempstring1, "1 (symbol is after amount)");
  4616.     } else
  4617.     {   strcat(tempstring1, "?");
  4618.     }
  4619.     AddNameToTail(&List2, tempstring1);
  4620.  
  4621.     strcpy(tempstring1, "First day of the week:  ");
  4622.     if (*(offset + 463) == 0)
  4623.     {   strcat(tempstring1, "0 (Sunday)");
  4624.     } elif (*(offset + 463) == 1)
  4625.     {   strcat(tempstring1, "1 (Monday)");
  4626.     } elif (*(offset + 463) == 2)
  4627.     {   strcat(tempstring1, "2 (Tuesday)");
  4628.     } elif (*(offset + 463) == 3)
  4629.     {   strcat(tempstring1, "3 (Wednesday)");
  4630.     } elif (*(offset + 463) == 4)
  4631.     {   strcat(tempstring1, "4 (Thursday)");
  4632.     } elif (*(offset + 463) == 5)
  4633.     {   strcat(tempstring1, "5 (Friday)");
  4634.     } elif (*(offset + 463) == 6)
  4635.     {   strcat(tempstring1, "6 (Saturday)");
  4636.     } else
  4637.     {   strcat(tempstring1, "?");
  4638.     }
  4639.     AddNameToTail(&List2, tempstring1);
  4640. }
  4641.  
  4642. AGLOBAL void iff_die(void)
  4643. {   IOBuffer[19] = iff.raw;
  4644. }
  4645.  
  4646. AGLOBAL void iff_config(void)
  4647. {   iff.raw = IOBuffer[19];
  4648. }
  4649.  
  4650.